二分查找
- 数组必须是有顺序的。
- 如果遍历结束,left>=right;
- 可以获取最左侧的数和最右侧的数。
正常程序
每个表变量都要有定义,这里面的[left,right],这里是闭区间。
public int search(int[] nums, int target) {
int left = 0, right = nums.length;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
leetcode_33 搜索旋转排序数组
将升序的数组nums,在第k位进行旋转。k,k+1...0,1,2...搜索数组中的值。 思路:二分查找要在有顺序中查找,要保证一侧是有序的。如果不在有序的一侧,就在另一侧
public int search(int[] nums, int target) {
int left = 0,right = nums.length-1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[left] <= nums[mid]) {
if (target >= nums[left] && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (target <= nums[right] && target > nums[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
leetcode_81 搜索旋转排序数组
这个和上面的那个差不多,这是这里面有重复元素。当left,mid,right都相等时,这种情况需要特殊处理。例如[4,4,4,4,1,2,3,4,4,4,4,4,4,4,4]。left,mid,right的值都是4,所以需要将这个情况特殊处理。
public boolean search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[left] == nums[mid] && nums[mid] == nums[right]) {
left++;
right--;
continue;
}
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1;
} else {
right = mid -1;
}
}
}
return false;
}
leetcode_34 在排序的数组中查找元素的第一个和最后一个位置
找到目标值的第一个和最后一个位置。正常的二分查找在找到元素后就返回。找最左侧的位置,要将while(left<=writh)循环完。在nums[mid]==target时,也要将right=mid-1;并将此时的mid进行记录。right=mid-1,有可能会比targe小,但是在等于时已经进行了记录。
public int[] searchRange(int[] nums, int target) {
int[] arr = new int[2];
arr[0] = searchLeftIndex(nums, target);
arr[1] = searchRightIndex(nums, target);
return arr;
}
public int searchLeftIndex(int[] nums, int target) {
int left = 0, right = nums.length - 1;
int res = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
res = mid;
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
}
public int searchRightIndex(int[] nums, int target) {
int left = 0, right = nums.length - 1;
int res = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
res = mid;
left = mid + 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
}