Kth Smallest Element in a Sorted Matrix

huangapple go评论60阅读模式
英文:

Kth Smallest Element in a Sorted Matrix

问题

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int n = matrix.length;
        int left = matrix[0][0];  // smallest element in the matrix
        int right = matrix[n - 1][n - 1];  // largest element in the matrix
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            int count = countLessEqual(matrix, mid);
            if (count < k) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        
        return left;
    }
    
    private int countLessEqual(int[][] matrix, int target) {
        int count = 0;
        int n = matrix.length;
        int row = n - 1;
        int col = 0;
        
        while (row >= 0 && col < n) {
            if (matrix[row][col] <= target) {
                count += row + 1;  // count elements in this column
                col++;
            } else {
                row--;
            }
        }
        
        return count;
    }
}

输入1: [[1,5,9],[10,11,13],[12,13,15]]
k = 8

输入2: [[1,2],[1,3]]
k = 1

输出1: 13
输出2: 1

请注意,我已经按照你的要求,仅提供了代码部分的翻译。这段代码使用了二分查找和计数方法来寻找第 k 小的元素,并且没有使用 Arrays.sort 或其他快捷排序技巧。

英文:

So I am working on a Leetcode question and my code works for some cases but fails for certain cases.

Here is the question:

> Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
>
> Note that it is the kth smallest element in the sorted order, not the kth distinct element.
>
> Example:
>
&gt; matrix = [[1, 5, 9], [10, 11, 13], [12, 13, 15]]
&gt; k = 8
&gt;

> return: 13

My approach is to use a minHeap, even if it stated that the array is sorted I still needed to make sure that I have it sorted from least to greatest value.

Here is my code:

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int row = matrix.length;
        int col = matrix[0].length;
        int result = 0;

        HashMap&lt;Integer, Integer&gt; map = new HashMap&lt;&gt;();
        //populate HashMap 
        for (int i = 0; i &lt; row; i++) {
            for (int j = 0; j &lt; col; j++) {
                map.put(matrix[i][j],
                        map.getOrDefault(matrix[i][j], 0) + 1);
            }
        }

        PriorityQueue&lt;Map.Entry&lt;Integer, Integer&gt;&gt; pq =
                new PriorityQueue&lt;&gt;((n1, n2) -&gt; n1.getValue() - n2.getValue());

        pq.addAll(map.entrySet());

        for (int i = 0; i &lt; k &amp;&amp; !(pq.isEmpty()); i++) {
            result = pq.poll().getKey();
        }

        return result;
    }
}

Here are my inputs:

Input 1: [[1,5,9],[10,11,13],[12,13,15]] 
k = 8 

Input 2: [[1,2],[1,3]] 
k = 1 

Here are the outputs:

Output 1: 13
Output 2: 2

Notice that the code works just fine for my first input where the 8th smallest element in the 2d-array is 13, but for the second input, the code is returning 2 as my first smallest element rather than returning 1.

Can someone please help me fix the code? I ask that you please not implement some fancy shorthand sorting technique e.g. Arrays.sort... it's not ideal for me as I am trying to learn how to implement heaps. Thanks a bunch Kth Smallest Element in a Sorted Matrix

答案1

得分: 1

以下是翻译好的代码部分:

public class Solution {
    public static final int kthSmallest(final int[][] matrix, final int k) {
        int lo = matrix[0][0];
        int hi = matrix[matrix.length - 1][matrix[0].length - 1] + 1;

        while (lo < hi) {
            final int mid = lo + (hi - lo) / 2;
            int count = 0;
            int col = matrix[0].length - 1;

            for (int row = 0; row < matrix.length; ++row) {
                while (col >= 0 && matrix[row][col] > mid) {
                    col--;
                }
                count += (col + 1);
            }
            if (count < k) {
                lo = mid + 1;
            } else {
                hi = mid;
            }
        }
        return lo;
    }
}
英文:

For solving this problem we can also binary search (a bit more efficient):

public class Solution {
    public static final int kthSmallest(final int[][] matrix, final int k) {
        int lo = matrix[0][0];
        int hi = matrix[matrix.length - 1][matrix[0].length - 1] + 1;

        while (lo &lt; hi) {
            final int mid = lo + (hi - lo) / 2;
            int count = 0;
            int col = matrix[0].length - 1;

            for (int row = 0; row &lt; matrix.length; ++row) {
                while (col &gt;= 0 &amp;&amp; matrix[row][col] &gt; mid) {
                    col--;
                }
                count += (col + 1);
            }
            if (count &lt; k) {
                lo = mid + 1;
            } else {
                hi = mid;
            }
        }
        return lo;
    }
}

答案2

得分: 0

你可以使用flatMapToInt方法在一个流中迭代遍历二维数组的行:

public static void main(String[] args) {
    int[][] matrix1 = {{1, 5, 9}, {10, 11, 13}, {12, 13, 15}};
    int[][] matrix2 = {{1, 2}, {1, 3}};

    System.out.println(kthSmallest(matrix1, 8)); // 13
    System.out.println(kthSmallest(matrix2, 1)); // 1
}
public static int kthSmallest(int[][] matrix, int k) {
    return Arrays.stream(matrix)
            .flatMapToInt(Arrays::stream)
            .skip(k - 1)
            .findFirst()
            .getAsInt();
}
英文:

You can use the flatMapToInt method to iterate over the rows of a 2d array in one stream:

public static void main(String[] args) {
    int[][] matrix1 = {{1, 5, 9}, {10, 11, 13}, {12, 13, 15}};
    int[][] matrix2 = {{1, 2}, {1, 3}};

    System.out.println(kthSmallest(matrix1, 8)); // 13
    System.out.println(kthSmallest(matrix2, 1)); // 1
}
public static int kthSmallest(int[][] matrix, int k) {
    return Arrays.stream(matrix)
            .flatMapToInt(Arrays::stream)
            .skip(k - 1)
            .findFirst()
            .getAsInt();
}

答案3

得分: 0

public static int kthSmallest(int[][] matrix, int k) {
    return Arrays
            .stream(matrix)
            .flatMapToInt(x -> Arrays.stream(x))
            .sorted()
            .skip(k - 1)
            .findFirst()
            .getAsInt();
}
英文:
public static int kthSmallest(int[][] matrix, int k) {
    return Arrays
            .stream(matrix)
            .flatMapToInt(x -&gt; Arrays.stream(x))
            .sorted()
            .skip(k-1)
            .findFirst()
            .getAsInt();
}

答案4

得分: 0

public static int kthSmallestNumber(int[][] matrix, int k) {
    return Arrays.stream(matrix).flatMapToInt(x -> Arrays.stream(x))
            .distinct()
            .sorted()
            .skip(k - 1)
            .findFirst()
            .getAsInt();
}
英文:
public static int kthSmallestNumber(int[][] matrix, int k) {
		
		return Arrays.stream(matrix).flatMapToInt(x-&gt;Arrays.stream(x))
				.distinct()
				.sorted()
				.skip(k-1)
				.findFirst()
				.getAsInt();
		
	}

huangapple
  • 本文由 发表于 2020年9月28日 20:11:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64101949.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定