二分查找的使用
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
二分查找中间山峰数字
二分查找左边是否有需要的元素
二分查找右边是否有需要的元素
剑指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就不会错误
以上是关于二分查找的使用的主要内容,如果未能解决你的问题,请参考以下文章