LintCode-排序矩阵中的从小到大第k个数

在一个排序矩阵中找从小到大的第 k 个整数。

排序矩阵的定义为:每一行递增,每一列也递增。

您在真实的面试中是否遇到过这个题?

Yes

样例

给出 k = 4 和一个排序矩阵:

[
  [1 ,5 ,7],
  [3 ,7 ,8],
  [4 ,8 ,9],
]

返回 5

挑战

使用O(k log n)的方法,n为矩阵的宽度和高度中的最大值。

标签 Expand

相关题目 Expand

分析:一般这种题都是用一个最大/最小堆,每次取出其中最大/最小的一个,然后把和这个数相关的(比它大/小)数压入堆中,知道找到第k大/小。

代码:

class Solution {
public:
    /**
     * @param matrix: a matrix of integers
     * @param k: an integer
     * @return: the kth smallest number in the matrix
     */
    int kthSmallest(vector<vector<int> > &matrix, int k) {
        // write your code here
        int n = matrix.size();
        int m = matrix[0].size();
        priority_queue<pair<int,pair<int,int> >,vector<pair<int,pair<int,int> > >,greater<pair<int,pair<int,int>> >> q;
        map<pair<int,int>,bool> visited;
        q.push(make_pair(matrix[0][0],make_pair(0,0)));
        visited[make_pair(0,0)]=true;
        while(k--)
        {
            pair<int,pair<int,int> > cur = q.top();
            if(k==0)
                return cur.first;
            q.pop();
            if(cur.second.first+1<n&&visited[make_pair(cur.second.first+1,cur.second.second)]==false)
            {
                q.push(make_pair(matrix[cur.second.first+1][cur.second.second],make_pair(cur.second.first+1,cur.second.second)));
                visited[make_pair(cur.second.first+1,cur.second.second)]=true;
            }
            if(cur.second.second+1<m&&visited[make_pair(cur.second.first,cur.second.second+1)]==false)
            {
                q.push(make_pair(matrix[cur.second.first][cur.second.second+1],make_pair(cur.second.first,cur.second.second+1)));
                visited[make_pair(cur.second.first,cur.second.second+1)]=true;
            }
        }
    }
};

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 22:33:20

LintCode-排序矩阵中的从小到大第k个数的相关文章

找到排序矩阵中从小到大第K个数字

一 题目描述 在一个排序矩阵中找从小到大的第 k 个整数. 排序矩阵的定义为:每一行递增,每一列也递增. 二 题解 由于排序矩阵中的每一行都是递增的,并且每一列都是递增的.从小到大第k个数,实际上就是第k小的数.思路如下: 假设排序矩阵共有row行和col列,由于每行是递增的,我们只要选择出每行的最小数(一共row个)并从这row个数中选出最小的数来,重复这个过程k次,第k次选择出的最小值就是整个矩阵中第k小的数. 代码如下: class Solution { public: /** * @pa

统计01矩阵中全1子矩阵的个数

统计01矩阵中全1子矩阵的个数 1.51Nod 1291 题意:600*600的01矩阵,统计宽i高j的全1矩阵的个数. 题解:枚举矩阵的下边界,对于每个下边界,统计所有宽极大的矩形的答案(高度可以用差分).\(n^2\) 统计完之后,我们已知所有高度的宽极大的答案,列一下式子发现两次前缀和就是最后答案. 代码: #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define mp

算法初级面试题03——队列实现栈、栈实现队列、转圈打印矩阵、旋转矩阵、反转链表、之字打印矩阵、排序矩阵中找数

第一部分主要讨论:栈.队列.数组矩阵相关的面试题 题目一 用数组结构实现大小固定的队列和栈 public static class ArrayStack { private Integer[] arr; private Integer size; public ArrayStack(int initSize) { if (initSize < 0) { throw new IllegalArgumentException("The init size is less than 0"

找出一堆数中最小的前K个数

描写叙述: 给定一个整数数组.让你从该数组中找出最小的K个数 思路: 最简洁粗暴的方法就是将该数组进行排序,然后取最前面的K个数就可以. 可是,本题要求的仅仅是求出最小的k个数就可以,用排序能够但显然有点浪费.比方让求10000个整数数组中的最小的10个数.用排序的话平均时间复杂度差为Nlog(N). 于是想到了,用堆来实现,可是自己实现又太麻烦.想到了java里面的TreeSet,先将K个数放入TreeSet中.因为TreeSet会对里面的元素进行排序.所以在TreeSet中的元素是有序的.以

【剑指Offer学习】【面试题38:数字在排序数组中出现的次数】

题目:统计一个数字:在排序数组中出现的次数. 举例说明 例如输入排序数组{ 1, 2, 3, 3, 3, 3, 4, 5}和数字3 ,由于3 在这个数组中出现了4 次,因此输出4 . 解题思路 利用改进的二分算法. 如何用二分查找算法在数组中找到第一个k,二分查找算法总是先拿数组中间的数字和k作比较.如果中间的数字比k大,那么k只有可能出现在数组的前半段,下一轮我们只在数组的前半段查找就可以了.如果中间的数字比k小,那么k只有可能出现在数组的后半段,下一轮我们只在数组的后半乓查找就可以了.如果中

剑指Offer面试题30(java版):最小的k个数

题目:输入n个整数,找出其中最小的k个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4 这道题最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数.这种思路的时间复杂度是O(nlogn),面试官会提示我们还有更快的算法. 解法一:O(n)的算法,只有当我们可疑修改输入的数组时可用 从上一题中我们可以得到启发,我们同样可以基于Partition函数来解决这个问题.如果基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数

【编程之美】2.5 寻找最大的k个数

有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2个多小时,反思,太慢了. 注意边界条件,不要混混沌沌的. /************我自己的解法*****************/ //选择数组a[N]中最大的第k个数 int Select(int * a, int N, int k) { if(k > N || a == NULL) { cou

编程之美2.5 寻找最大的K个数

在一个数组中寻找最大的K个数,我们首先说一种非常简单的方法,利用快速排序中的分割算法,即我们经常看见的partition.这个函数会返回一个 int 类型的值,这个值代表的是前一半数字和后一半数字的分割点,前一半数字都小于等于后一半数字(递增排序),所以,我们只要找到相对应的分割点,即可以找到最大的K个数,或者最小的K个数,这就是利用线性方法可以完成任务的方法. 首先,给出函数声明: int DutPartition(int*, int, int); void DutFindMaxKInArra

编程之美之2.5 寻找最大的K个数

[题目] 有很多无序的数,从中找出最大的K个数.假定他们都不相等. [解法一] 如果数据不是很多,例如在几千个左右,我们可以排一下序,从中找出最大的K个数.排序可以选择快速排序或者堆排序 [cpp] view plaincopy #include<stdio.h> #include<stdlib.h> int cmp(const void *a,const void *b){ return *(int *)a - *(int *)b; } int main(){ int n,k;