二分查找题目

二分查找

    • 检查一个数是否在数组中占绝大多数
    • 不动点
    • 猜数字大小
    • 第 k 个缺失的正整数
    • 找出数组排序后的目标下标
    • 早餐组合
    • 第一个错误的版本
    • 采购方案
    • 和为s的两个数字
    • 排序数组中两个数字之和
    • 查找插入位置
    • 山峰数组的顶部
    • 求平方根
    • 最接近的二叉搜索树值


检查一个数是否在数组中占绝大多数


二分查找题目_第1张图片
二分查找题目_第2张图片

class Solution {
    public int leftest(int[] nums,int target){
        int left=0,right=nums.length-1;
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(nums[mid]>=target){
                right=mid;
            }
            else{
                left=mid+1;
            }
        }
        return left;
    }
    public int rightest(int[] nums,int target){
        int left=0,right=nums.length-1;
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(nums[mid]>target){
                right=mid;
            }
            else{
                left=mid+1;
            }
        }
        return left;
    }
    public boolean isMajorityElement(int[] nums, int target) {
        
        //二分找出等于target最左的位置
        int left=leftest(nums,target);

        //二分找出等于target最右的位置
        int right=rightest(nums,target);
        if(left==right){
            return false;
        }
        return right-left+1>nums.length/2;
    }
}

二分查找题目_第3张图片



不动点


二分查找题目_第4张图片

二分查找题目_第5张图片

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

二分查找题目_第6张图片



猜数字大小


二分查找题目_第7张图片
二分查找题目_第8张图片

/** 
 * Forward declaration of guess API.
 * @param  num   your guess
 * @return 	     -1 if num is lower than the guess number
 *			      1 if num is higher than the guess number
 *               otherwise return 0
 * int guess(int num);
 */

public class Solution extends GuessGame {
    public int guessNumber(int n) {
        
        int left=1,right=n;
        int mid=0;
        while(left<=right){
            mid=left+((right-left)>>1);
            if(guess(mid)==0)return mid;
            else if(guess(mid)>0){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
}

二分查找题目_第9张图片

第 k 个缺失的正整数


二分查找题目_第10张图片
二分查找题目_第11张图片

class Solution {
    public int findKthPositive(int[] arr, int k) {
        int left=0,right=arr.length-1;
        if(arr[arr.length-1]==arr.length)return arr[arr.length-1]+k;
        if(arr[0]-1>=k){
            return k;
        }else{
            k-=(arr[0]-1);
        }
        
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(left==mid)break;
            //if(k==0)break;
            else if(arr[mid]-arr[left]-(mid-left)>0){
                if(arr[mid]-arr[left]-(mid-left)<k){
                    k-=arr[mid]-arr[left]-(mid-left);
                    left=mid;
                }else{
                    right=mid;
                }    
            }else{
                left=mid;
            }
        }
        if(left<arr.length-1){
            if(arr[left]+1==arr[left+1]){
                return arr[arr.length-1]+k;
            }else{
                return arr[left+1]-arr[left]-1>=k?arr[left]+k:arr[left+1]+(k-(arr[left+1]-arr[left]-1));
            }
        }
        return arr[left]+k;
    }
}

二分查找题目_第12张图片



找出数组排序后的目标下标


二分查找题目_第13张图片

二分查找题目_第14张图片

class Solution {
    public int leftest(int[] nums,int target){
        int left=0,right=nums.length-1;
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
    public int rightest(int[] nums,int target){
        int left=0,right=nums.length-1;
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(nums[mid]<=target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
    public List<Integer> targetIndices(int[] nums, int target) {
        Arrays.sort(nums);
        //二分找出等于target最左的位置
        int left=leftest(nums,target);
        //二分找出等于target最右的位置
        int right=rightest(nums,target);
        List<Integer>list=new ArrayList<>();
        for(int i=left;i<=right;++i){
            if(nums[i]==target){
                list.add(i);
            }
        }
        return list;

    }
}

二分查找题目_第15张图片



早餐组合


二分查找题目_第16张图片
二分查找题目_第17张图片

class Solution {

    //O(NlogN)
    public int breakfastNumber(int[] staple, int[] drinks, int x) {
        //排序
        Arrays.sort(staple);
        Arrays.sort(drinks);
        int ans=0;
        int index=0;
        for(int s=0;s<staple.length;++s){
            if(staple[s]>=x)break;
            int rest=x-staple[s];
            //二分查找drinks数组中大于rest的最左的位置
            index=getIndex(drinks,rest);
            if(rest<drinks[index]){
                ans+=index;
            }else{
                ans+=index+1;
            }
            ans%=1000000007;
        }
        return ans%1000000007;
    }
    public int getIndex(int[] drinks,int x){
        int left=0,right=drinks.length-1;
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(drinks[mid]>x){
                right=mid-1;
            }else{
                left=mid+1;
            }
        }
        return left;
    }
}

二分查找题目_第18张图片



第一个错误的版本


二分查找题目_第19张图片

二分查找题目_第20张图片

/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left=1,right=n;
        int mid=0;
        while(left<=right){
            mid=left+((right-left)>>1);
            if(isBadVersion(mid)){
                right=mid-1;
            }else{
                left=mid+1;
            }
        }
        return left;
    }
}

二分查找题目_第21张图片



采购方案

二分查找题目_第22张图片

在这里插入图片描述

class Solution {
    
    //先排序再二分
    public int fun(int[] nums,int target){
        Arrays.sort(nums);
        int ans=0;
        for(int i=0;i<nums.length-1;++i){
            if(nums[i]>=target)break;
            //二分找到比target-nums[i]大的最左位置
            int index=getIndex(nums,target-nums[i],i+1,nums.length-1);
            if(target-nums[i]>=nums[index]){
                ans+=(index-i);
            }else{
                ans+=(index-i-1);
            }
            ans%=1000000007;
        }
        return ans%1000000007;
    }
    public int getIndex(int[] nums,int x,int left,int right){
        if(left==right)return left;
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(nums[mid]>x){
                right=mid-1;
            }else{
                left=mid+1;
            }
        }
        return left;
    }
    public int purchasePlans(int[] nums, int target) {
        // return process(nums,0,2,target);
        // return DP(nums,target);
        return fun(nums,target);
    }
}

二分查找题目_第23张图片



和为s的两个数字

二分查找题目_第24张图片

class Solution {
    public int index(int[] nums,int x,int left,int right){
        int mid=0;
        while(left<right){
            mid=left+((right-left)>>1);
            if(nums[mid]==x)return mid;
            else if(nums[mid]<x){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
    public int[] twoSum(int[] nums, int target) {
        int[] ans=new int[2];
        for(int i=0;i<nums.length-1;++i){
            int cur=index(nums,target-nums[i],i+1,nums.length-1);
            if(target-nums[i]==nums[cur]){
                ans[0]=nums[i];
                ans[1]=target-nums[i];
                break;
            }
        }
        return ans;
    }
}

二分查找题目_第25张图片



排序数组中两个数字之和

二分查找题目_第26张图片

二分查找题目_第27张图片

class Solution {
    public int index(int[] numbers,int x,int left,int right){
        int mid=0;
        while(left<right){
//        	System.out.println(left+" "+right);
        	mid=left+((right-left)>>1);
            if(numbers[mid]==x)return mid;
            else if(numbers[mid]<x){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
    public int[] twoSum(int[] numbers, int target) {

        int[] ans=new int[2];
        int cur=0;
        for(int i=0;i<numbers.length-1;++i){
        	
            cur=index(numbers,target-numbers[i],i+1,numbers.length-1);
            
            if(numbers[cur]==target-numbers[i]){
                ans[0]=i;
                ans[1]=cur;
                break;
            }
        }
        return ans;
    }
}

二分查找题目_第28张图片



查找插入位置

二分查找题目_第29张图片

二分查找题目_第30张图片


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

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

二分查找题目_第31张图片



山峰数组的顶部

二分查找题目_第32张图片

二分查找题目_第33张图片

class Solution {

    //O(N)解法
    public int process1(int[] arr){
        for(int i=0;i<arr.length-1;++i){
            if(arr[i]>arr[i+1]){
                return i;
            }
        }
        return 0;
    }
    //O(longN)解法
    //二分查找
    public int process2(int[] arr){
        int left=0,right=arr.length-1;
        int mid=0;
        while(left<=right){
            mid=left+((right-left)>>1);
            if(mid==0){
                left=mid+1;
            }
            else if(mid==arr.length-1){
                right=mid-1;
            }
            else if(arr[mid]>arr[mid-1]&&arr[mid]>arr[mid+1]){
                return mid;
            }else if(arr[mid]>arr[mid-1]&&arr[mid]<arr[mid+1]){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return 0;
    }
    public int peakIndexInMountainArray(int[] arr) {
        // return process1(arr);
        return process2(arr);
    }
}

二分查找题目_第34张图片



求平方根

二分查找题目_第35张图片

class Solution {
    public int mySqrt(int x) {
        if(x==0||x==1)return x;
        long left=1,right=x/2;
        long mid=left+((right-left)>>1);
        while(left<=right){
            mid=left+((right-left)>>1);
            if(mid*mid==x){
                break;
            }
            else if(mid*mid<x){
                if((mid+1)*(mid+1)>x)break;
                left=mid+1;
            }
            else{
                right=mid-1;
            }
        }
        return (int)mid;
    }
}

二分查找题目_第36张图片



最接近的二叉搜索树值


二分查找题目_第37张图片

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    public int closestValue(TreeNode root, double target) {
        TreeNode cur=root;
        int ans=0;
        double min=Integer.MAX_VALUE;
        while(cur!=null){
            if(min>=Math.abs(cur.val-target)){
                min=Math.abs(cur.val-target);
                ans=cur.val;
            }
            if(target<cur.val){
                cur=cur.left;
            }else{
                cur=cur.right;
            }
        }
        
        return ans;
    }
}

二分查找题目_第38张图片

你可能感兴趣的:(leetcode,二分查找)