# [378. 有序矩阵中第 K 小的元素](https://leetcode.cn/problems/kth-smallest-element-in-a-sorted-matrix) [English Version](/solution/0300-0399/0378.Kth%20Smallest%20Element%20in%20a%20Sorted%20Matrix/README_EN.md) ## 题目描述 <!-- 这里写题目描述 --> <p>给你一个 <code>n x n</code><em> </em>矩阵 <code>matrix</code> ,其中每行和每列元素均按升序排序,找到矩阵中第 <code>k</code> 小的元素。<br /> 请注意,它是 <strong>排序后</strong> 的第 <code>k</code> 小元素,而不是第 <code>k</code> 个 <strong>不同</strong> 的元素。</p> <p>你必须找到一个内存复杂度优于 <code>O(n<sup>2</sup>)</code> 的解决方案。</p> <p> </p> <p><strong>示例 1:</strong></p> <pre> <strong>输入:</strong>matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8 <strong>输出:</strong>13 <strong>解释:</strong>矩阵中的元素为 [1,5,9,10,11,12,13,<strong>13</strong>,15],第 8 小元素是 13 </pre> <p><strong>示例 2:</strong></p> <pre> <strong>输入:</strong>matrix = [[-5]], k = 1 <strong>输出:</strong>-5 </pre> <p> </p> <p><strong>提示:</strong></p> <ul> <li><code>n == matrix.length</code></li> <li><code>n == matrix[i].length</code></li> <li><code>1 <= n <= 300</code></li> <li><code>-10<sup>9</sup> <= matrix[i][j] <= 10<sup>9</sup></code></li> <li>题目数据 <strong>保证</strong> <code>matrix</code> 中的所有行和列都按 <strong>非递减顺序</strong> 排列</li> <li><code>1 <= k <= n<sup>2</sup></code></li> </ul> <p> </p> <p><strong>进阶:</strong></p> <ul> <li>你能否用一个恒定的内存(即 <code>O(1)</code> 内存复杂度)来解决这个问题?</li> <li>你能在 <code>O(n)</code> 的时间复杂度下解决这个问题吗?这个方法对于面试来说可能太超前了,但是你会发现阅读这篇文章( <a href="http://www.cse.yorku.ca/~andy/pubs/X+Y.pdf" target="_blank">this paper</a> )很有趣。</li> </ul> ## 解法 <!-- 这里可写通用的实现逻辑 --> 二分法。 <!-- tabs:start --> ### **Python3** <!-- 这里可写当前语言的特殊实现逻辑 --> ```python class Solution: def kthSmallest(self, matrix: List[List[int]], k: int) -> int: def check(matrix, mid, k, n): count = 0 i, j = n - 1, 0 while i >= 0 and j < n: if matrix[i][j] <= mid: count += (i + 1) j += 1 else: i -= 1 return count >= k n = len(matrix) left, right = matrix[0][0], matrix[n - 1][n - 1] while left < right: mid = (left + right) >> 1 if check(matrix, mid, k, n): right = mid else: left = mid + 1 return left ``` ### **Java** <!-- 这里可写当前语言的特殊实现逻辑 --> ```java class Solution { public int kthSmallest(int[][] matrix, int k) { int n = matrix.length; int left = matrix[0][0], right = matrix[n - 1][n - 1]; while (left < right) { int mid = (left + right) >>> 1; if (check(matrix, mid, k, n)) { right = mid; } else { left = mid + 1; } } return left; } private boolean check(int[][] matrix, int mid, int k, int n) { int count = 0; int i = n - 1, j = 0; while (i >= 0 && j < n) { if (matrix[i][j] <= mid) { count += (i + 1); ++j; } else { --i; } } return count >= k; } } ``` ### **C++** ```cpp class Solution { public: int kthSmallest(vector<vector<int>>& matrix, int k) { int n = matrix.size(); int left = matrix[0][0], right = matrix[n - 1][n - 1]; while (left < right) { int mid = left + right >> 1; if (check(matrix, mid, k, n)) { right = mid; } else { left = mid + 1; } } return left; } private: bool check(vector<vector<int>>& matrix, int mid, int k, int n) { int count = 0; int i = n - 1, j = 0; while (i >= 0 && j < n) { if (matrix[i][j] <= mid) { count += (i + 1); ++j; } else { --i; } } return count >= k; } }; ``` ### **Go** ```go func kthSmallest(matrix [][]int, k int) int { n := len(matrix) left, right := matrix[0][0], matrix[n-1][n-1] for left < right { mid := (left + right) >> 1 if check(matrix, mid, k, n) { right = mid } else { left = mid + 1 } } return left } func check(matrix [][]int, mid, k, n int) bool { count := 0 i, j := n-1, 0 for i >= 0 && j < n { if matrix[i][j] <= mid { count += (i + 1) j++ } else { i-- } } return count >= k } ``` ### **...** ``` ``` <!-- tabs:end -->