二分查找的使用

Posted 划小船

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找的使用相关的知识,希望对你有一定的参考价值。

简单的二分查找

704. Binary Search

Description

Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1.

Example 1:

Input: nums = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in nums and its index is 4

Example 2:

Input: nums = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: 2 does not exist in nums so return -1

Constraints:

  • 1 <= nums.length <= 104

  • -9999 <= nums[i], target <= 9999

  • All the integers in nums are unique.

  • nums is sorted in an ascending order.

Solution

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

山脉数组中的二分查找

1095. Find in Mountain Array

Description

(This problem is an interactive problem.)

You may recall that an array A is a mountain array if and only if:

  • A.length >= 3

  • There exists some i with 0 < i < A.length - 1 such that:

A[0] < A[1] < ... A[i-1] < A[i]
A[i] > A[i+1] > ... > A[A.length - 1]

Given a mountain array mountainArr, return the minimum index such that mountainArr.get(index) == target.  If such an index doesn't exist, return -1.

You can't access the mountain array directly.  You may only access the array using a MountainArray interface:

  • MountainArray.get(k) returns the element of the array at index k (0-indexed).

  • MountainArray.length() returns the length of the array.

  • Submissions making more than 100 calls to MountainArray.get will be judged Wrong Answer.  Also, any solutions that attempt to circumvent the judge will result in disqualification.

Example 1:

Input: array = [1,2,3,4,5,3,1], target = 3
Output: 2
Explanation: 3 exists in the array, at index=2 and index=5. Return the minimum index, which is 2.

Example 2:

Input: array = [0,1,2,4,2,1], target = 3
Output: -1
Explanation: 3 does not exist in the array, so we return -1.

Constraints:

  • 3 <= mountain_arr.length() <= 10000

  • 0 <= target <= 10^9

  • 0 <= mountain_arr.get(index) <= 10^9

Solution

/**
 * // This is MountainArray's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface MountainArray {
 *     public int get(int index) {}
 *     public int length() {}
 * }
 */


class Solution {
    public int findInMountainArray(int target, MountainArray mountainArr) {
        int l = 0;
        int length = mountainArr.length() - 1;
        int r = length;
        int mid = 0;

        //find mountain peak
        //if peak is target return peak
        //because peak is unique
        while(r>l){
            mid = (r + l) / 2;
            int mider = mountainArr.get(mid);
            int higher = mountainArr.get(mid + 1);
            int lower = mountainArr.get(mid - 1);
            if(mider > higher && mider > lower) {
                if(mider == target) {
                    return mid;
                }
                break;
            }
            if(mider<lower){
                r = mid;
            }
            if(mider<higher){
                l = mid + 1;
            }
        }

        //check left side
        l = 0;
        int r1 = mid;
        while(r1 > l){
            int mid1 = (r1 + l) / 2;
            int mider = mountainArr.get(mid1);

            if(mider == target) {
                return mid1;
            }

            if(mider > target) {
                r1 = mid1;                
            }

            if(mider < target) {
                l = mid1 + 1;                
            }
        }

        //check right side
        int l2 = mid + 1;
        int r2 = length;
        while (l2 <= r2) {
            int mid2 = (l2 + r2)  / 2;
            int mider = mountainArr.get(mid2);

            if (mider == target){
                return mid2;
            }

            if (mider < target){
                r2 = mid2 - 1;    
            }else{
                l2 = mid2 + 1;
            }
        }

        return -1;
    }
}

Discuss

  1. 二分查找中间山峰数字

  2. 二分查找左边是否有需要的元素

  3. 二分查找右边是否有需要的元素

剑指offer-旋转数组中的最小数字

Description

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组[3,4,5,1,2]为[1,2,3,4,5]的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

Solution

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array == null || array.length == 0){
          return 0;
        }
        int low = 0, high = array.length-1;
        while(low < high){
           int mid = low + (high-low)/2;
           if(array[mid]>array[high]){
              low = mid+1;
           }else if(array[mid]==array[high]){
              high = high -1;
           }else{
              high = mid;
           }
        }
        return array[low];
    }
}

Discuss


采用二分法mid = low + (high - low)/2解答这个问题

需要考虑三种情况:

  • (1) array[mid] > array[high]:
    出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。
    low = mid + 1

  • (2) array[mid] == array[high]:
    出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边
    还是右边,这时只好一个一个试
    high = high - 1

  • (3) array[mid] < array[high] :
    出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左边。因为右边必然都是递增的。
    high = mid

  • 注意这里有个坑:如果待查询的范围最后只剩两个数,那么mid 一定会指向下标靠前的数字,比如 array = [4,6]; array[low] = 4 ;array[mid] = 4 ; array[high] = 6 ; 如果high = mid - 1,就会产生错误, 因此high = mid; 但情形(1)中low = mid + 1就不会错误

以上是关于二分查找的使用的主要内容,如果未能解决你的问题,请参考以下文章

java泛型 二分查找

二分查找常见套路与分析

二分查找常见套路与分析

二分查找--整理

算法——二分查找

代码题(12)— 二分查找