面试题笔记-算法-力扣-二分查找

本文介绍如何使用二分查找算法优化求平方根,并探讨了在矩阵搜索中利用数组特性加速查找过程。通过实例展示了如何处理有序数组和特殊等值情况,提升搜索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
根据题意要找的是平方小于x且最接近的数。如此可以想到用二分法查找
完整代码如下:

public static int mySqrt(int x) {
        int start = 0;
        int end = x;
        while (start <= end) {
            int temp = (start + end) / 2;
            Long sum = (long)temp * temp;
            if(sum == x) return temp;
            else if(sum > x) {
                end = temp - 1;
            }
            else {
                start = temp + 1;
            }
        }

        return (start + end) / 2;

    }

在这里插入图片描述
按顺序排列来查找就可以用二分查找

public static boolean searchMatrix(int[][] matrix, int target) {
        int startRow = 0;
        int endRow = matrix.length - 1;
        int targetRow = 0;

        int startCol = 0;
        int endCol = matrix[0].length - 1;


        while (startRow <= endRow) {
            int mid = (startRow + endRow) / 2;
            if(matrix[mid][startCol] > target){
                endRow = mid - 1;
            }else if(matrix[mid][endCol] < target){
               startRow = mid + 1;
            }else {
                if(matrix[mid][startCol] == target || matrix[mid][endCol] == target) return true;
                targetRow = mid;
                break;
            }
        }

        while (startCol <= endCol) {
            int mid = (startCol + endCol) / 2;
            if(matrix[targetRow][mid] == target) return true;
            else if(matrix[targetRow][mid] < target) startCol = mid + 1;
            else endCol = mid - 1;
        }
        return false;

    }

在这里插入图片描述
读题可知,该数组是由单向递增的数组转置而来。
所以当取mid将数组分成两段的时候至少有一段是有序的。
则可一开始进行判断mid在左还在右

if(mid_num >= nums[0]) flag = true;//左半边
            else flag = false;//右半边

当然有可能会有三个数相等的情况如:
1,1,1,1,1,1,1,1,2,1
此时则需要进行另一种讨论
直接缩小范围进行下一轮的查询

if (nums[left] == nums[mid] && nums[right] == nums[mid]){
                left++;
                right--;
                continue;
            }

对于能够分出左右两段的数组

if(target < nums[mid] && target > nums[left] && flag){//target 落在左边
                right = mid - 1;
                continue;
            } else if (target > nums[mid] && target < nums[right] && !flag) {//落在右边
                left = mid + 1;
                continue;
            }else { //在外
                if(flag) left = mid + 1;
                else right = mid - 1;
            }

完整代码如下:

public static boolean search(int[] nums, int target) {
        boolean flag;//标记mid 在左半边 还是右半边
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            int mid_num = nums[mid];
            if(mid_num == target || nums[left] == target || nums[right] == target) return true;

        if (nums[left] == nums[mid] && nums[right] == nums[mid]){
                left++;
                right--;
                continue;
            }

            if(mid_num >= nums[0]) flag = true;//左半边
            else flag = false;//右半边

            if(target < nums[mid] && target > nums[left] && flag){//target 落在左边
                right = mid - 1;
                continue;
            } else if (target > nums[mid] && target < nums[right] && !flag) {//落在右边
                left = mid + 1;
                continue;
            }else { //在外
                if(flag) left = mid + 1;
                else right = mid - 1;
            }
        }
        return false;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值