关闭

378. Kth Smallest Element in a Sorted Matrix leetcode binary_search 378

标签: binary searchleetcode378Kth Smallest Element
152人阅读 评论(0) 收藏 举报
分类:
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:

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

return 13.

Note: 
You may assume k is always valid, 1 ≤ k ≤ n2.

 

这道题让我们求有序矩阵中第K小的元素,这道题的难点在于数组并不是蛇形有序的,意思是当前行的最后一个元素并不一定会小于下一行的首元素,所以我们并不能直接定位第K小的元素,所以只能另辟蹊径。先来看一种利用堆的方法,我们使用一个最大堆,然后遍历数组每一个元素,将其加入堆,根据最大堆的性质,大的元素会排到最前面,然后我们看当前堆中的元素个数是否大于k,大于的话就将首元素去掉,循环结束后我们返回堆中的首元素即为所求:

 

解法一:

复制代码
class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        priority_queue<int, vector<int>> q;
        for (int i = 0; i < matrix.size(); ++i) {
            for (int j = 0; j < matrix[i].size(); ++j) {
                q.emplace(matrix[i][j]);
                if (q.size() > k) q.pop();
            }
        }
        return q.top();
    }
};
复制代码

 

这题我们也可以用二分查找法来做,我们由于是有序矩阵,那么左上角的数字一定是最小的,而右下角的数字一定是最大的,所以这个是我们搜索的范围,然后我们算出中间数字mid,由于矩阵中不同行之间的元素并不是严格有序的,所以我们要在每一行都查找一下mid,我们使用upper_bound,这个函数是查找第一个大于目标数的元素,如果目标数在比该行的尾元素大,则upper_bound返回该行元素的个数,如果目标数比该行首元素小,则upper_bound返回0, 我们遍历完所有的行可以找出中间数是第几小的数,然后k比较,进行二分查找,本解法的整体时间复杂度为O(nlgn*lgX),其中X为最大值和最小值的差值,参见代码如下:

 

解法二:

复制代码
class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int left = matrix[0][0], right = matrix.back().back();
        while (left < right) {
            int mid = left + (right - left) / 2, cnt = 0;
            for (int i = 0; i < matrix.size(); ++i) {
                cnt += upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin();
            }
            if (cnt < k) left = mid + 1;
            else right = mid;
        }
        return left;
    }
};
复制代码

 

上面的解法还可以进一步优化到O(nlgX),其中X为最大值和最小值的差值,我们并不用对每一行都做二分搜索法,我们注意到每列也是有序的,我们可以利用这个性质,从数组的左下角开始查找,如果比目标值小,我们就向右移一位,而且我们知道当前列的当前位置的上面所有的数字都小于目标值,那么cnt += i+1,反之则向上移一位,这样我们也能算出cnt的值。其余部分跟上面的方法相同,参见代码如下:

 

解法三:

复制代码
class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int left = matrix[0][0], right = matrix.back().back();
        while (left < right) {
            int mid = left + (right - left) / 2;
            int cnt = search_less_equal(matrix, mid);
            if (cnt < k) left = mid + 1;
            else right = mid;
        }
        return left;
    }
    int search_less_equal(vector<vector<int>>& matrix, int target) {
        int n = matrix.size(), i = n - 1, j = 0, res = 0;
        while (i >= 0 && j < n) {
            if (matrix[i][j] <= target) {
                res += i + 1;
                ++j;
            } else {
                --i;
            }
        }
        return res;
    }
};
复制代码

 

参考资料:

https://discuss.leetcode.com/topic/52857/c-priority_queue-ac-implementation

https://discuss.leetcode.com/topic/52865/my-solution-using-binary-search-in-c

https://discuss.leetcode.com/topic/53041/java-1ms-nlog-max-min-solution

 

LeetCode All in One 题目讲解汇总(持续更新中...)


0
0
查看评论

LeetCode—378. Kth Smallest Element in a Sorted Matrix

Kth Smallest Element in a Sorted Matrix思路:1.首先这题把所有的数组遍历出来然后直接排序就可以AC..... 2.正常思路就是维系最大堆。 GitHub地址:https://github.com/corpsepiges/leetcode ...
  • corpsepiges
  • corpsepiges
  • 2016-08-02 10:20
  • 2144

LeetCode 378. Kth Smallest Element in a Sorted Matrix 解题报告

LeetCode 378. Kth Smallest Element in a Sorted Matrix 解题报告
  • camellhf
  • camellhf
  • 2016-10-07 23:29
  • 339

[leetcode] 378. Kth Smallest Element in a Sorted Matrix

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...
  • TstsUgeg
  • TstsUgeg
  • 2016-08-02 16:38
  • 1310

[leetcode] 378. Kth Smallest Element in a Sorted Matrix 解题报告

题目链接: https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/ Given a n x n matrix where each of the rows an...
  • qq508618087
  • qq508618087
  • 2016-08-20 15:43
  • 1408

【leetcode】378. Kth Smallest Element in a Sorted Matrix

一、题目描述 Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in t...
  • xiaoquantouer
  • xiaoquantouer
  • 2016-08-06 13:21
  • 1666

【Leetcode】Kth Smallest Element in a Sorted Matrix

题目链接:https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/ 题目: Given a n x n matrix where each of the rows ...
  • yeqiuzs
  • yeqiuzs
  • 2016-08-01 21:54
  • 3287

378. Kth Smallest Element in a Sorted Matrix

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...
  • wdlsjdl2
  • wdlsjdl2
  • 2016-08-01 11:02
  • 1338

leetcode_378 Kth Smallest Element in a Sorted Matrix

题目分析给定一个n*n的矩阵,其中每一行每一列都按照递增排序,寻找矩阵中的第k小元素。注意,是要寻找排好序的第k小元素,而不是第k个不重复元素。 解题思路1)利用堆来实现。直接维护一个大小为k的堆,全部读入一边,这样平均和最好时间情况都为O(n*logk)。 2)利用二分查找实现。 C++实现 s...
  • yzhang6_10
  • yzhang6_10
  • 2016-09-14 22:17
  • 536

401.Kth Smallest Number in Sorted Matrix-排序矩阵中的从小到大第k个数(中等题)

排序矩阵中的从小到大第k个数 题目在一个排序矩阵中找从小到大的第 k 个整数。 排序矩阵的定义为:每一行递增,每一列也递增。 样例给出 k = 4 和一个排序矩阵: 挑战使用O(k log n)的方法,n为矩阵的宽度和高度中的最大值。 题解使用优先队列进行最小堆排序,每次选取最小的元素,第K次选...
  • Tri_Color_Flag
  • Tri_Color_Flag
  • 2016-11-15 22:47
  • 804

LeetCode 230: Kth Smallest Element in a BST

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Note: You may assume k is always valid, 1 ≤ k ≤ BST&...
  • sunao2002002
  • sunao2002002
  • 2015-07-02 14:27
  • 5601
    个人资料
    • 访问:82484次
    • 积分:2333
    • 等级:
    • 排名:第18876名
    • 原创:149篇
    • 转载:71篇
    • 译文:0篇
    • 评论:3条
    最新评论