📌  相关文章
📜  Java程序在按行排序的矩阵中查找中位数

📅  最后修改于: 2022-05-13 01:54:57.269000             🧑  作者: Mango

Java程序在按行排序的矩阵中查找中位数

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

Input : 1 3 5
        2 6 9
        3 6 9
Output : Median is 5
If 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 9
Output: Median is 5

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

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

下面是上述方法的实现:

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 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


输出:

Median is 5

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

有关详细信息,请参阅有关在按行排序的矩阵中查找中位数的完整文章!