二分法-中等难度

二分法

东西其实并不难,如果你理解不了,说明教的不好

二分法实际是一个比较简单的方法

基础的原理:在一个排序好的数组中,寻找一个值,可以看中间元素值的大小,跟目标值进行比较,确定以一个搜索范围,每次搜索范围可以减半,搜索效率大大提升。

二分法一个写的比较清楚的视频 分享给大家: leetcode34

二分法的解题模板:

public int binarySearch(int[] nums, int target){
    int left = 0;
	int right = nums.length;
    int ans = -1;
    while(left<=right){ // 这个等号很有学问,如果后面left,right=mid,等号不能加,如果=mid+1或mid-1,需要加=号
        int mid= left+(right-left)/2; // 这块可以避免(left+right)/2引入的溢出问题
       	if(nums[mid]< target){
            left = mid+1;
        } else if(nums[mid]> target){
            right = mid-1;
        } else{
            // 这块的代码是核心,需要按照不同题目好好设计,设计好了问题会很简单
            ans = mid;
        }
        return ans;
    }
}

力扣上的部分二分法题目及我的答案

[34. 在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/)

class Solution {
    public int[] searchRange(int[] nums, int target) {

        int firstIndex = binarySearch(nums, target, true);
        if (firstIndex == -1) {
            return new int[]{-1, -1};
        }
        int lastIndex = binarySearch(nums, target, false);
        return new int[]{firstIndex, lastIndex};

    }

    public int binarySearch(int[] nums, int target, boolean first) {
        int left = 0;
        int right = nums.length - 1;
        int ans = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                if (first) {
                    right = mid - 1;
                    ans = mid;
                } else {
                    left = mid + 1;
                    ans = mid;
                }

            }
        }
        return ans;
    }
}

[33. 搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/)

class Solution {
    public int search(int[] nums, int target) {
        int conv = findConvert(nums) + 1;
        int ans1 = binarySearch(Arrays.copyOfRange(nums, 0, conv), target);
        int ans2 = binarySearch(Arrays.copyOfRange(nums, conv, nums.length), target);

        if (ans1 != -1) {
            return ans1;
        } else if (ans2 != -1) {
            return ans2 + conv;
        } else {
            return -1;
        }
    }

    public int findConvert(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        int ans = -1;
        while (left < right) {
            final int mid = left + (right - left) / 2;
            if (nums[mid] <= nums[left]) {
                right = mid;
                ans = mid;
            } else {
                left = mid;
            }
        }
        return ans;
    }

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

[74. 搜索二维矩阵](https://leetcode-cn.com/problems/search-a-2d-matrix/)

class Solution {
 public boolean searchMatrix(int[][] matrix, int target) {
        int[] nums = new int[matrix.length * matrix[0].length];
        int count = 0;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                nums[count++] = matrix[i][j];
            }
        }
        return binarySearch(nums, target);

    }

    public boolean binarySearch(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) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                return true;
            }
        }
        return false;
    }
}
posted @ 2021-12-02 17:38  Oh,mydream!  阅读(100)  评论(0编辑  收藏  举报