458. Last Position of Target 思路: 相等的时候抛弃左边
public class Solution {
/**
* @param nums: An integer array sorted in ascending order
* @param target: An integer
* @return: An integer
*/
public int lastPosition(int[] nums, int target) {
// write your code here
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] <= target) {
start = mid;
} else {
end = mid;
}
}
if (nums[end] == target) {
return end;
}
if (nums[start] == target) {
return start;
}
return -1;
}
}
14. First Position of Target
- 思路: 相等的时候抛弃右边
public class Solution {
/**
* @param nums: The integer array.
* @param target: Target to find.
* @return: The first position of target. Position starts from 0.
*/
public int binarySearch(int[] nums, int target) {
// write your code here
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] >= target) {
end = mid;
} else {
start = mid;
}
}
if (nums[start] == target) {
return start;
}
if (nums[end] == target) {
return end;
}
return -1;
}
}
28. Search a 2D Matrix
public class Solution {
/**
* @param matrix: matrix, a list of lists of integers
* @param target: An integer
* @return: a boolean, indicate whether matrix contains target
*/
public boolean searchMatrix(int[][] matrix, int target) {
// write your code here
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int start = 0;
int rows = matrix.length;
int cols = matrix[0].length;
int end = rows * cols - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (matrix[mid / cols][mid % cols] <= target) {
start = mid;
} else {
end = mid;
}
}
if (matrix[end / cols][end % cols] == target || matrix[start / cols][start % cols] == target) {
return true;
}
return false;
}
}
LeetCode. 240. Search a 2D Matrix II 思路: 左下 到 右上
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int rows = matrix.length;
int cols = matrix[0].length;
int startRow = rows - 1;
int startCol = 0;
// System.out.println("startRow: " + startRow);
// System.out.println("startCol: " + startCol);
// 注意判断这里的越界条件
while (startRow >= 0 && startRow < rows && startCol >= 0 && startCol < cols) {
// System.out.println("startRow: " + startRow);
// System.out.println("startCol: " + startCol);
if (matrix[startRow][startCol] == target) {
return true;
} else if (matrix[startRow][startCol] < target) {
startCol = startCol + 1;
} else {
startRow = startRow - 1;
}
}
return false;
}
}
Lint61. Search for a Range
- 思路: First Position + Last Postion 扫两遍
public class Solution {
/**
* @param A: an integer sorted array
* @param target: an integer to be inserted
* @return: a list of length 2, [index1, index2]
*/
public int[] searchRange(int[] nums, int target) {
// write your code here
if (nums == null || nums.length == 0) {
return new int[]{-1, -1};
}
int[] res = new int[2];
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] >= target) {
end = mid;
} else {
start = mid;
}
}
if (nums[start] == target) {
res[0] = start;
} else if (nums[end] == target) {
res[0] = end;
} else {
return new int[]{-1, -1};
}
start = 0;
end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] <= target) {
start = mid;
} else {
end = mid;
}
}
if (nums[end] == target) {
res[1] = end;
} else if (nums[start] == target) {
res[1] = start;
} else {
return new int[]{-1, -1};
}
return res;
}
}
Lint62. Search in Rotated Sorted Array
- 思路: 需要同时判断在哪个区间上 Last Element是标志
刚才想复杂了,其实就是在判断二分的时候,需要check target和两个端点值,而不能只是check一个值,
因为仅仅满足target > nums[start] 或 target < nums[mid] 都不能够保证舍弃右半边的所有元素 来让end = mid
, 只有当
切割完成之后还是一个rotated sorted array, 可以继续二分下去
public class Solution {
/**
* @param A: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[start] < nums[mid]) {
if (nums[start] <= target && target <= nums[mid]) {
end = mid;
} else {
start = mid;
}
} else {
if (nums[mid] <= target && target <= nums[end]) {
start = mid;
} else {
end = mid;
}
}
}
if (nums[start] == target) {
return start;
}
if (nums[end] == target) {
return end;
}
return -1;
}
}
Follow Up: 存在重复值
159. Find Minimum in Rotated Sorted Array
- 找最小一定要有比较 nums[i] < nums[i + 1] nums[i] < nums[i - 1]
public class Solution {
/**
* @param nums: a rotated sorted array
* @return: the minimum number in the array
*/
public int findMin(int[] nums) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0, end = nums.length - 1;
int target = nums[nums.length - 1];
// find the first element <= target
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] <= target) {
end = mid;
} else {
start = mid;
}
}
// 这里必定存在最小值,所以不需要返回 -1
if (nums[start] <= target) {
return nums[start];
} else {
return nums[end];
}
}
}
Lint585.Maximum Number in Mountain Sequence
public class Solution {
/**
* @param nums a mountain sequence which increase firstly and then decrease
* @return then mountain top
*/
public int mountainSequence(int[] nums) {
// Write your code here
if (nums == null || nums.length == 0) {
return 0;
}
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
// 这里的OOXX的特点是 nums[mid] > nums[mid + 1] 找到第一个nums[mid] <= nums[mid + 1]的时候就停了
if (nums[mid] > nums[mid + 1]) {
end = mid;
} else {
start = mid;
}
}
return Math.max(nums[start], nums[end]);
}
}
Find Peak Element
public class Solution {
/*
* @param A: An integers array.
* @return: return any of peek positions.
*/
public int findPeak(int[] A) {
// write your code here
int start = 0;
int end = A.length - 2;
while(start + 1 < end){
int mid = start + (end - start) / 2;
//如果中间的数比后一位数大的话,peek点肯定在mid左边或是mid。
//如果中间的数比前一位数小的话,peek点肯定在mid右边或是mid。
if(A[mid]>A[mid + 1]){
end = mid;
} else {
start = mid;
}
}
if(A[start] < A[end]){
return end;
} else {
return start;
}
}
}