leetcode 69, 278, 153, 378, 34, 162 (binary search)

这篇博客探讨了二分查找算法在不同场景下的应用,包括寻找有序数组中的目标值、找到平方根的整数部分、在部分有序数组中找边界以及峰值元素等。文章通过多个LeetCode问题实例,详细解释了如何根据问题特性调整二分查找的实现,展示了二分查找的灵活性和效率。
摘要由CSDN通过智能技术生成

Template1

//因为mid对于长度为偶数的区间总是偏左的,所以当区间长度小于等于2时,mid 总是和 left在同一侧。
class BinarySearch {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target) return mid;
            else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

Solution for leetcode 69

https://leetcode.com/problems/sqrtx/

class Solution {
    public int mySqrt(int x) {
        if(x == 0){
            return 0;
        }
        if(x == 1){
            return 1;
        }
        int left = 1;
        int right = x / 2;
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(Math.pow(mid,2) == x){
                return mid;
            }
            else if(Math.pow(mid,2) > x){
                right = mid - 1;
            }
            else{
                //another step to check
                if(Math.pow(mid + 1, 2) > x){
                    return mid;
                }
                left = mid + 1;
            }
        }
        return -1;
    }
}

Template 2.1

Used to find the left boudary 

  1. the array is in order,but contains duplicates
  2. the array is partly in order,and it doens't contain duplicates
class Solution {
    public int search(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 {
                right = mid;
            }
        }
        return nums[left] == target ? left : -1;
    }
}

Solution for leetcode 278

https://leetcode.com/problems/first-bad-version/

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1;
        int right = n;
        //when left and right are adjacent to each other, mid、left and right will 
        //go to the same position in the next iteration. Then, if we go to the else 
        //part in this next iteration, we will have an infinite loop
        while(left < right){
            int mid = left + (right - left) / 2;
            if(isBadVersion(mid) == false){
                left = mid + 1;
            }
            else{
                //after finding the bad, we need to continue to find the left boundary
                right = mid;
            }
        }
        return isBadVersion(left) ? left : -1; 
    }
}

Solution for leetcode153

https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/

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

Solution for leetcode 378 (binary search in a matrix)

https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int n = matrix.length;
        int left = matrix[0][0];
        int right = matrix[n - 1][n - 1];
        while(left < right){
            int mid = left + (right - left) / 2;
            if(check(matrix, k, mid, n) == false){
                left = mid + 1;
            }
            else{
                right = mid;
            }
        }
        return left;
        
    }
    public boolean check(int[][]matrix, int k, int mid,int n){
        int y = 0;
        int x = n - 1;
        int count = 0;
        while(x >= 0 && y < n){
            if(matrix[x][y] <= mid){
                count += x + 1;
                y++;
            }
            else{
                x--;
            }
        }
        return count >= k;
    }
}

Template 2.2 

Used to find the right boundary: Pay attention that we need to add one at the end

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

Solution for leetcode 34 

a combination of finding the left and right boundaries. When we find the right boundary, we start from the previous left boundary. And we deal with the special cases 1) the left boundary is the last position 2) there is only one element that is the same as the target

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int left = 0;
        int[] output = new int[]{-1,-1};
        if(nums == null || nums.length == 0) return output;
        int right = nums.length - 1;
        while(left < right){
            int mid = left + (right - left) / 2;
            if(nums[mid] < target){
                left = mid + 1;
            }
            else{
                right = mid;
            }
        }
        output[0] = nums[left] == target ? left : -1;
        if(output[0] != -1){
            if(left == nums.length -1 || nums[left + 1] != target){
                output[1] = left;
            }
            else{
                right = nums.length - 1;
                while(left < right){
                    int mid = left + (right - left) / 2 + 1;
                    if(nums[mid] > target){
                        right = mid - 1;
                    }
                    else{
                        left = mid;
                    }
                }
                output[1] = right;
            }
        }
        return output;  
    }
}

2.3 Find peak element

Solution for leetcode 162

https://leetcode.com/problems/find-peak-element/

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值