两道找第k小元素利口378_668

378. Kth Smallest Element in a Sorted Matrix

在一个矩阵中找到第k小的元素,矩阵可包含重复值,每行,每列递增。

利用二分法主要是要找到区间,并不断缩小。区间又主要来自两个地方:序列号和元素值,大部分都是依据数组的序列号,也有小部分是通过元素值,本体就是。

  1. l设为矩阵最小值,r为最大值
  2. 每次取其中值m,计算矩阵中小于m的元素的个数count
  3. 如果count小于k,说明m最多是第count小的,而第k小的元素肯定比m大,往m值后面找
  4. 否则,第k小的元素肯定小于等于m,往前面继续找
public int kthSmallest(int[][] matrix, int k) {
    int l = matrix[0][0], r = matrix[matrix.length-1][matrix[0].length-1] + 1;

    while (l < r) {
        int m = l + (r - l) / 2;
        int count = 0, j = matrix[0].length-1;

        //计算小于m的个数count
        for (int i = 0; i < matrix.length; i++) {
            while (j >=0 && matrix[i][j] > m)
                j--;
            count += j+1;
        }

        //如果count小于k,说明m最多是第count小的,而第k小的元素肯定比m大,往m值后面找
        //否则,第k小的元素肯定小于等于m,往前面继续找
        if (count < k)
            l = m + 1;
        else
            r = m;
    }
    return l;
}

668. Kth Smallest Number in Multiplication Table

和上题几乎一样,只是矩阵换成了一个乘法表,找第k小的元素。

  1. 首先乘法表是固定的,给出了m,n,k。我们就可以比较这几个值的大小来缩小查找范围,比如m > k,那么大于k的部分就没有看的必要了,因为大于k的所有行肯定全都大于k
  2. 剩下的解题结构和上题也几乎一样,只不过每次循环算大于m的元素个数的计算方式发生了变化
public int findKthNumber(int m, int n, int k) {
	//缩小范围
    int i = Math.min(m, k);
    int j = Math.min(n, k);

    int l = 1, r = i * j;
    while (l < r) {
        int mid = l + (r - l) / 2;
        int count = 0;
        for (int o1 = 1; o1 <= i; o1++) {
        	//计算每行小于mid的元素个数
            int o2 = Math.min(mid/o1, j);
            count += o2;
        }
        if (count < k)
            l = mid + 1;
        else
            r = mid;
    }
    return l;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值