在按行排序的矩阵中求中值

我们得到一个大小为r*c的按行排序矩阵,我们需要找到给定矩阵的中值。假设r*c总是奇数。 例如:

null
Input : 1 3 5        2 6 9        3 6 9Output : Median is 5If we put all the values in a sorted array A[] = 1 2 3 3 5 6 6 9 9)Input: 1 3 4       2 5 6       7 8 9Output: Median is 5

简单方法 :解决这个问题的最简单方法是将给定矩阵的所有元素存储在大小为r*c的数组中。然后我们可以对数组进行排序,并在O(r*clog(r*c))中找到中值元素,或者我们可以使用讨论的方法 在这里 求O(r*c)中的中值。两种情况下所需的辅助空间均为O(r*c)。 一 有效的方法 对于这个问题,使用 二进制搜索 算法。这个想法是,对于一个要成为中值的数字,应该有正好(n/2)个小于这个数字的数字。所以,我们试图找到比所有数字都少的数字。下面是这种方法的逐步算法: 算法 :

  1. 首先,我们找到矩阵中的最小和最大元素。通过比较每行的第一个元素可以很容易地找到最小元素,同样,通过比较每行的最后一个元素可以找到最大元素。
  2. 然后我们对从最小值到最大值的数字范围进行二进制搜索,找到最小值和最大值的中间值,得到一个小于或等于中间值的数字,并相应地改变最小值或最大值。
  3. 对于一个要成为中值的数字,应该有(r*c)/2个比该数字小的数字。因此,对于每一个数字,我们通过在矩阵的每一行中使用上界()来得到小于该数字的计数,如果它小于所需计数,则中值必须大于所选数字,否则中值必须小于或等于所选数字。

以下是上述方法的实施情况:

C++

// C++ program to find median of a matrix
// sorted row wise
#include<bits/stdc++.h>
using namespace std;
const int MAX = 100;
// function to find median in the matrix
int binaryMedian( int m[][MAX], int r , int c)
{
int min = INT_MAX, max = INT_MIN;
for ( int i=0; i<r; i++)
{
// Finding the minimum element
if (m[i][0] < min)
min = m[i][0];
// Finding the maximum element
if (m[i][c-1] > max)
max = m[i][c-1];
}
int desired = (r * c + 1) / 2;
while (min < max)
{
int mid = min + (max - min) / 2;
int place = 0;
// Find count of elements smaller than mid
for ( int i = 0; i < r; ++i)
place += upper_bound(m[i], m[i]+c, mid) - m[i];
if (place < desired)
min = mid + 1;
else
max = mid;
}
return min;
}
// driver program to check above functions
int main()
{
int r = 3, c = 3;
int m[][MAX]= { {1,3,5}, {2,6,9}, {3,6,9} };
cout << "Median is " << binaryMedian(m, r, c) << endl;
return 0;
}


JAVA

// Java program to find median of a matrix
// sorted row wise
import java.util.Arrays;
public class MedianInRowSorted
{
// function to find median in the matrix
static int binaryMedian( int m[][], int r, int c)
{
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for ( int i= 0 ; i<r ; i++)
{
// Finding the minimum element
if (m[i][ 0 ] < min)
min = m[i][ 0 ];
// Finding the maximum element
if (m[i][c- 1 ] > max)
max = m[i][c- 1 ];
}
int desired = (r * c + 1 ) / 2 ;
while (min < max)
{
int mid = min + (max - min) / 2 ;
int place = 0 ;
int get = 0 ;
// Find count of elements smaller than mid
for ( int i = 0 ; i < r; ++i)
{
get = Arrays.binarySearch(m[i],mid);
// If element is not found in the array the
// binarySearch() method returns
// (-(insertion_point) - 1). So once we know
// the insertion point we can find elements
// Smaller than the searched element by the
// following calculation
if (get < 0 )
get = Math.abs(get) - 1 ;
// If element is found in the array it returns
// the index(any index in case of duplicate). So we go to last
// index of element which will give  the number of
// elements smaller than the number including
// the searched element.
else
{
while (get < m[i].length && m[i][get] == mid)
get += 1 ;
}
place = place + get;
}
if (place < desired)
min = mid + 1 ;
else
max = mid;
}
return min;
}
// Driver Program to test above method.
public static void main(String[] args)
{
int r = 3 , c = 3 ;
int m[][]= { { 1 , 3 , 5 }, { 2 , 6 , 9 }, { 3 , 6 , 9 } };
System.out.println( "Median is " + binaryMedian(m, r, c));
}
}
// This code is contributed by Sumit Ghosh


Python3

# Python program to find median of matrix
# sorted row wise
from bisect import bisect_right as upper_bound
MAX = 100 ;
# Function to find median in the matrix
def binaryMedian(m, r, d):
mi = m[ 0 ][ 0 ]
mx = 0
for i in range (r):
if m[i][ 0 ] < mi:
mi = m[i][ 0 ]
if m[i][d - 1 ] > mx :
mx = m[i][d - 1 ]
desired = (r * d + 1 ) / / 2
while (mi < mx):
mid = mi + (mx - mi) / / 2
place = [ 0 ];
# Find count of elements smaller than mid
for i in range (r):
j = upper_bound(m[i], mid)
place[ 0 ] = place[ 0 ] + j
if place[ 0 ] < desired:
mi = mid + 1
else :
mx = mid
print ( "Median is" , mi)
return
# Driver code
r, d = 3 , 3
m = [ [ 1 , 3 , 5 ], [ 2 , 6 , 9 ], [ 3 , 6 , 9 ]]
binaryMedian(m, r, d)
# This code is contributed by Sachin BIsht


C#

// C# program to find median
// of a matrix sorted row wise
using System;
class MedianInRowSorted{
// Function to find median
// in the matrix
static int binaryMedian( int [,]m,
int r, int c)
{
int max = int .MinValue;
int min = int .MaxValue;
for ( int i = 0; i < r; i++)
{
// Finding the minimum
// element
if (m[i, 0] < min)
min = m[i, 0];
// Finding the maximum
// element
if (m[i, c - 1] > max)
max = m[i, c - 1];
}
int desired = (r * c + 1) / 2;
while (min < max)
{
int mid = min + (max - min) / 2;
int place = 0;
int get = 0;
// Find count of elements
// smaller than mid
for ( int i = 0; i < r; ++i)
{
get = Array.BinarySearch(
GetRow(m, i), mid);
// If element is not found
// in the array the binarySearch()
// method returns (-(insertion_
// point) - 1). So once we know
// the insertion point we can
// find elements Smaller than
// the searched element by the
// following calculation
if ( get < 0)
get = Math.Abs( get ) - 1;
// If element is found in the
// array it returns the index(any
// index in case of duplicate). So
// we go to last index of element
// which will give  the number of
// elements smaller than the number
// including the searched element.
else
{
while ( get < GetRow(m, i).GetLength(0) &&
m[i, get ] == mid)
get += 1;
}
place = place + get ;
}
if (place < desired)
min = mid + 1;
else
max = mid;
}
return min;
}
public static int [] GetRow( int [,] matrix,
int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int [rowLength];
for ( var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// Driver code
public static void Main(String[] args)
{
int r = 3, c = 3;
int [,]m = {{1,3,5},
{2,6,9},
{3,6,9} };
Console.WriteLine( "Median is " +
binaryMedian(m, r, c));
}
}
// This code is contributed by Princi Singh


Javascript

<script>
// Javascript program to find median
// of a matrix sorted row wise
// Function to find median
// in the matrix
function binaryMedian(m, r, c)
{
var max = -1000000000;
var min = 1000000000;
for ( var i = 0; i < r; i++)
{
// Finding the minimum
// element
if (m[i][0] < min)
min = m[i][0];
// Finding the maximum
// element
if (m[i] > max)
max = m[i];
}
var desired =  parseInt((r * c + 1) / 2);
while (min < max)
{
var mid = min + parseInt((max - min) / 2);
var place = 0;
var get = 0;
// Find count of elements
// smaller than mid
for ( var i = 0; i < r; ++i)
{
var tmp = GetRow(m, i);
for ( var j = tmp.length; j>=0; j--)
{
if (tmp[j] <= mid)
{
get = j+1;
break ;
}
}
// If element is not found
// in the array the binarySearch()
// method returns (-(insertion_
// point) - 1). So once we know
// the insertion point we can
// find elements Smaller than
// the searched element by the
// following calculation
if (get < 0)
get = Math.abs(get) - 1;
// If element is found in the
// array it returns the index(any
// index in case of duplicate). So
// we go to last index of element
// which will give  the number of
// elements smaller than the number
// including the searched element.
else
{
while (get < GetRow(m, i).length &&
m[i][get] == mid)
get += 1;
}
place = place + get;
}
if (place < desired)
min = mid + 1;
else
max = mid;
}
return min;
}
function GetRow(matrix, row)
{
var rowLength = matrix[0].length;
var rowVector = Array(rowLength).fill(0);
for ( var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row][i];
return rowVector;
}
// Driver code
var r = 3, c = 3;
var m = [[1,3,5],
[2,6,9],
[3,6,9]];
document.write( "Median is " +
binaryMedian(m, r, c));
// This code is contributed by rutvik_56.
</script>


输出

Median is 5

时间复杂性 :O(32*r*log(c))。上限函数将花费log(c)时间,并针对每一行执行。由于数字的最大值为32位,所以从最小值到最大值的二进制搜索将在最多32(log2(2^32)=32)个操作中执行。 辅助空间 :O(1)

本文由 阿卡什·阿加瓦尔 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享