zoukankan      html  css  js  c++  java
  • 找到排序矩阵中从小到大第K个数字

    一 题目描述

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

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

    二 题解

    由于排序矩阵中的每一行都是递增的,并且每一列都是递增的。从小到大第k个数,实际上就是第k小的数。思路如下:

    假设排序矩阵共有row行和col列,由于每行是递增的,我们只要选择出每行的最小数(一共row个)并从这row个数中选出最小的数来,重复这个过程k次,第k次选择出的最小值就是整个矩阵中第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)
        {
            size_t row = matrix.size();
            size_t col = matrix[0].size();
            if(row == 0 || col == 0)
                return -1;
            int minRows[row];//用于存储每行的最小值对应的列数
            memset(minRows,0,sizeof(minRows));//对minRows初始化,且初始值都为0
            if(k > row * col)//错误处理
                return -1;
            int rs;
            int tmp;
            for(int cnt = 1; cnt <= k; cnt++)
            {
                int min_val = INT_MAX;//每次比较都需要初始化,注意该变量定义的位置
                for(int row_index = 0; row_index < row; row_index++)
                {
                    if(minRows[row_index] < col)//注意这个判断条件一定要加上,防止越界
                    {
                        if(matrix[row_index][minRows[row_index]] < min_val)
                        {
                            min_val = matrix[row_index][minRows[row_index]];
                            tmp = row_index;
                        }
                    }
                }
                minRows[tmp]++;//更新相应行中最小值的位置,要注意此处的位置,是在row轮循环之后才能找出最小值
                if(cnt == k)
                    rs = min_val;
            }
            return rs;
        }
    };
    

    该算法思路表简单,算法的时间复杂度为O(k*row),此外,有几个需要注意的地方:

    1.我们每次选择出的最小值指的是这row个数中的最小值,所以mi_val这个变量需要在每次循环开始的时候才定义,这里我定义的是INT_MAX,所以所有的行需要遍历一一遍。

    2.在每次进行row轮循环的时候,一定不要忘记判断,相应的值的列数的索引是否已经达到最大值。

    3.注意minRows数组更新的时候是在row轮循环结束的后才进行更新。

    ============================================================================================================

    此外,本题是从列的角度来考虑的,即每次找出一列数中的最小值来;,当然也可从行的角度来考虑,每次找出一行数中的最小值来,重复k次,第k次的最小值就是最终结果。两种方法思想类似,利用第二种方法的话时间复杂度就变成了O(k*col)。

    当列数大于行数的时候,用第一种方法比较好;而当行数大于列数的时候用第二种方法比较好,当然前提是行数和列数的差值比较大,否则两种方法性能差不多;当然,也可以结合这两种情况,对于行列数不同的情况时,采用不同方法。

  • 相关阅读:
    scrapy中selenium的应用
    Django的锁和事务
    redis
    【leetcode】187. Repeated DNA Sequences
    【leetcode】688. Knight Probability in Chessboard
    【leetcode】576. Out of Boundary Paths
    【leetcode】947. Most Stones Removed with Same Row or Column
    【leetcode】948. Bag of Tokens
    【leetcode】946. Validate Stack Sequences
    【leetcode】945. Minimum Increment to Make Array Unique
  • 原文地址:https://www.cnblogs.com/wangkundentisy/p/9388378.html
Copyright © 2011-2022 走看看