继续两道二分法利口74_4

74. Search a 2D Matrix

在一个有序的二维数组中找到指定值,有序指的是从左往右有序,从上往下也有序

  1. 就很简单了,和一维数组找指定值的区别就是查找两次,可以先通过最后一列数来找到target在上半段还是下半段,然后循环找到具体在哪一行
  2. 然后就在该行二分查找target就行了
public boolean searchMatrix(int[][] matrix, int target) {
    int top = 0, bottom = matrix.length - 1;
    int col = matrix[0].length - 1;

    int row = 0;
    while (top < bottom) {
        int mid = top + (bottom - top) / 2;
        if (matrix[mid][col] == target)
            return true;

        if (matrix[mid][col] > target)
            bottom = mid;
        else
            top = mid + 1;
    }
    row = top;

    int l = 0, r = col;
    while (l < r) {
        int m = l + (r - l) / 2;
        if (matrix[row][m] == target)
            return true;

        if (matrix[row][m] > target)
            r = m;
        else
            l = m + 1;
    }
    return matrix[col][l] == target;
}

注:当然也可以完全把二维数组看作一维的直接进行二分查找

4. Median of Two Sorted Arrays

找到两个有序数组的中值,要在log(m + n)时间复杂度内

就有点难度了,要想找到第k个值(k是两个数组合并起来后的中值所在位置),主要思想是不断在两个数组中找到第k/2个元素,进行比较,然后舍弃较小值的那个数组第k/2个元素的左边所有元素,然后缩小k值,继续循环。

为什么舍弃较小值的那个数组的第k/2个元素的左边所有元素呢

因为这些元素是肯定小于中值的,舍弃它们没啥问题,只要后面在修改k值就ok,修改k值就是减去这些元素的个数,因为这样要找的第k个值也就没发生变化了

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int l = (nums1.length + nums2.length + 1) / 2;
    int r = (nums1.length + nums2.length + 2) / 2;

    return (getKth(nums1, 0, nums2, 0, l) + getKth(nums1, 0, nums2, 0, r))/2;
}

public int getKth(int[] nums1, int startl, int[] nums2, int startr, int k) {
    if (startl > nums1.length - 1) return nums2[startr + k - 1];
    if (startr > nums2.length - 1) return nums1[startl + k - 1];

    if (k == 1) return Math.min(nums1[startl], nums2[startr]);

    int mid1 = Integer.MAX_VALUE;
    int mid2 = Integer.MAX_VALUE;
    if (startl + k/2 - 1 < nums1.length) mid1 = nums1[startl + k/2 - 1];
    if (startr + k/2 - 1 < nums2.length) mid2 = nums2[startr + k/2 - 1];

    if (mid1 < mid2)
        return getKth(nums1, startl+k/2, nums2, startr, k - k/2);
    else
        return getKth(nums1, startl, nums2, startr+k/2, k - k/2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值