1-leetcode35. 搜索插入位置
注意:×
- 看Labuladong的书,知道
while
的判断符号跟left right
的关系
public int searchInsert(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
}
}
return right+1;
}
leetcode74. 搜索二维矩阵
注意:√
- 跟之前一个题目很像,这种矩阵直接从左上角或者右下角进行查找即可
public boolean searchMatrix(int[][] matrix, int target) {
int n = 0;
int m = matrix[0].length - 1;
while (n < matrix.length && m >= 0) {
if (matrix[n][m] == target){
return true;
} else if (matrix[n][m] > target) {
m--;
} else if (matrix[n][m] < target) {
n++;
}
}
return false;
}
3-leetcode34. 在排序数组中查找元素的第一个和最后一个位置
注意:×
- 注意找左边界,是right移动–这个其实没问题
- 问题是:你移动的时候不可以
right == mid
,这样会死循环的(其实写的时候就能发现这个问题)所以直接给变化的值,因为后面会判断结果的 - 左边界,最下面的判读是判断左边界
- 右边界,最下面的判断是判断右边界
public int[] searchRange(int[] nums, int target) {
if (nums.length == 0) {
return new int[]{-1, -1};
}
int[] arr = new int[2];
arr[0] = findLeftBound(nums, target);
arr[1] = findRightBound(nums, target);
return arr;
}
private int findRightBound(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
}
}
if (right < 0) {
return -1;
}
return nums[right] == target ? right : -1;
}
private int findLeftBound(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
right = mid - 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
}
}
if (left == nums.length){
return -1;
}
return nums[left] == target? left: -1;
}
4-leetcode33. 搜索旋转排序数组
注意:×
- 通过最左边的数字跟
nums[mid]
进行对比,可以得到左边是 有序还是右边是有序的 - 然后判断target的落点
- 注意target和nums[left]的值的对比,不要漏掉相等的情况,即:
if (nums[mid] > target || nums[left] **<=** target){
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target){
return mid;
} else if (nums[left] <= nums[mid]) {
// 左边是有序的
if (nums[mid] < target || nums[left] > target){
left = mid + 1;
}else {
right = mid - 1;
}
} else if (nums[left] > nums[mid]) {
// 右边虽然反转了,但是右边是有序的
if (nums[mid] > target || nums[left] <= target){
right = mid - 1;
}else {
left = mid + 1;
}
}
}
return -1;
}
5-leetcode153. 寻找旋转排序数组中的最小值
注意:×
- 这个题不能跟上面那个题一样比较左边的值,会出错,因为上面那个只要找到哪边有序就行,但是在这题里面,有序不代表最小,
nums[mid] < nums[left]
无法得到最小值的位置,可能在左边也可能在右边 - 因为要找最小的那个的值,没有
target'
所以调整了right
的修改策略,注意注意!!!!!!!!!! - 第一编写反正是有点怪怪的感觉,不行就记下来吧
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[right] < nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left];
}