











如果没有设置循环,将没有效果

















public int search(int[] nums, int target) {
int n = nums.length;
if (n == 0) {
return -1;
}
if (n == 1) {
return nums[0] == target ? 0 : -1;
}
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return -1;
}
}

判断结果,一致输出左边的,不一致输出右边的:
return nums[0]==target ?0:-1;
x=s ? a:b;
如果测试错误,可从区间的开闭查找错误
当有重复元素存在的情况:
public boolean search(int[] nums, int target) {
int n = nums.length;
if (n == 0) {
return false;
}
if (n == 1) {
return nums[0] == target;
}
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
++l;
--r;
} else if (nums[l] <= nums[mid]) {
if (nums[l] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return false;
}
对于数组中有重复元素的情况,二分查找时可能会有 a[l]=a[\textit{mid}]=a[r]a[l]=a[mid]=a[r],此时无法判断区间 [l,\textit{mid}][l,mid] 和区间 [\textit{mid}+1,r][mid+1,r] 哪个是有序的。
例如 \textit{nums}=[3,1,2,3,3,3,3]nums=[3,1,2,3,3,3,3],\textit{target}=2target=2,首次二分时无法判断区间 [0,3][0,3] 和区间 [4,6][4,6] 哪个是有序的。
对于这种情况,我们只能将当前二分区间的左边界加一,右边界减一,然后在新区间上继续二分查找。
寻找旋转数组最小元素
class Solution {
public int findMin(int[] nums) {
int n=nums.length;
int left=0;int right=n-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(nums[mid]>=nums[(mid+1)%n])
return nums[(mid+1)%n];
if(nums[(mid+n-1)%n]>=nums[mid])
{
return nums[mid];
}
if(nums[mid]<nums[right])
right=mid;
else
left=mid+1;
}
return -1;
}
}
注意:如果担心越界异常,可以使用if(nums[mid]>=nums[(mid+1)%n])
进行加n取余的操作。