hot100-一刷-11二分查找(共6道题)

35. 搜索插入位置

题目链接

题目描述

image

代码实现

分析:

代码:

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = left + (right - left)/2;
            if(nums[mid] > target){
                right = mid - 1;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{ // nums[mid] == target
                return mid;
            }
        }
        return left;
    }
}

74. 搜索二维矩阵

题目链接

题目描述

image

代码实现

分析:

  • 巩固二分

代码:

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        int left = 0;
        int right = m*n - 1;
        while (left<=right){
            int mid = (left + right) >>> 1;
            int x = matrix[mid/n][mid % n];
            if ( target == x){
                return true;
            }
            if ( x < target){
                left = mid + 1;
            }else{
                right = mid -1;
            }
        }
        return false;
    }
}

34. 在排序数组中查找元素的第一个和最后一个位置

题目链接

题目描述

image

代码实现

分析:

代码:

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int start = lowerBound(nums, target);
        if (start == nums.length || nums[start] != target) {
            return new int[]{-1, -1}; // nums 中没有 target
        }
        // 如果 start 存在,那么 end 必定存在
        int end = lowerBound(nums, target + 1) - 1;
        return new int[]{start, end};
    }

    private int lowerBound(int[] nums, int target){
        int l = 0;
        int r = nums.length - 1;
        while(l <= r){
            int mid = (l + r) >>> 1;
            if(target <= nums[mid]){  // 小于等于都会将right赋值为mid-1,也就是把right一直左移动
                r = mid -1;
            }else {
                l = mid + 1;
            }
        }
        return l;
    }
}

33. 搜索旋转排序数组

题目链接

题目描述

image

代码实现

分析:

代码:

class Solution {
    public int search(int[] nums, int target) {
        int n = nums.length;
        int i = findMin4Index(nums);
        System.out.print(i);
        if(target > nums[n-1]) {
            // [0, i-1] 
            return lowerBound(nums, target, 0, i);
        }

        return lowerBound(nums, target, i, n-1);

    }
    
    private int findMin4Index(int[] nums){
        int n = nums.length;
        int l = 0;
        int r = n - 1;
        while(l <= r){
            int mid = l + (r - l) / 2;
            if (nums[mid] > nums[n-1]){
                l = mid + 1;
            }else {  // nums[mid] <= nums[n-1]
                r = mid - 1;
            }
        }
        return l;
    }

    private int lowerBound(int[] nums, int target, int l, int r){
        while (l <= r){
            int mid = l + (r - l) / 2;
            if(nums[mid] >= target) {
                r = mid - 1;
            }else {
                l = mid + 1;
            }
        }
        return (l < nums.length && nums[l] == target) ? l : -1;
    }
}

153. 寻找旋转排序数组中的最小值

题目链接

题目描述

image

代码实现

分析:
题解
image

代码:

class Solution {
    public int findMin(int[] nums) {
        int n = nums.length;
        int l = 0;
        int r = n - 2;
        //[0, n-2]
        // 最小值相当于我们的target
        while (l <= r) {
            int mid = l + (r - l) / 2;
            //  1️⃣     2️⃣
            //   /       /
            //  /         /
            // [M] > [end] 说明一定是翻转过,即2️⃣,且最小值一定是在第二段,[M]在第一段,左边染红色  
            if (nums[mid] > nums[n-1]) {
                l = mid + 1;
            } else {  // [M] < [end] 说明 [M]要么是最小值,要么在最小值的右边, 右边染蓝色
                r = mid - 1;
            }
        }
        return nums[l];
    }
}

题目

题目链接

题目描述

代码实现

分析:

代码:


posted @ 2024-12-23 11:30  chendsome  阅读(8)  评论(0编辑  收藏  举报