Template1
//因为mid对于长度为偶数的区间总是偏左的,所以当区间长度小于等于2时,mid 总是和 left在同一侧。
class BinarySearch {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) return mid;
else if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
}
Solution for leetcode 69
https://leetcode.com/problems/sqrtx/
class Solution {
public int mySqrt(int x) {
if(x == 0){
return 0;
}
if(x == 1){
return 1;
}
int left = 1;
int right = x / 2;
while(left <= right){
int mid = left + (right - left) / 2;
if(Math.pow(mid,2) == x){
return mid;
}
else if(Math.pow(mid,2) > x){
right = mid - 1;
}
else{
//another step to check
if(Math.pow(mid + 1, 2) > x){
return mid;
}
left = mid + 1;
}
}
return -1;
}
}
Template 2.1
Used to find the left boudary
- the array is in order,but contains duplicates
- the array is partly in order,and it doens't contain duplicates
class Solution {
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) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left] == target ? left : -1;
}
}
Solution for leetcode 278
https://leetcode.com/problems/first-bad-version/
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1;
int right = n;
//when left and right are adjacent to each other, mid、left and right will
//go to the same position in the next iteration. Then, if we go to the else
//part in this next iteration, we will have an infinite loop
while(left < right){
int mid = left + (right - left) / 2;
if(isBadVersion(mid) == false){
left = mid + 1;
}
else{
//after finding the bad, we need to continue to find the left boundary
right = mid;
}
}
return isBadVersion(left) ? left : -1;
}
}
Solution for leetcode153
https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
class Solution {
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] > nums[nums.length - 1]){
left = mid + 1;
}
else{
right = mid;
}
}
return nums[left];
}
}
Solution for leetcode 378 (binary search in a matrix)
https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/
class Solution {
public int kthSmallest(int[][] matrix, int k) {
int n = matrix.length;
int left = matrix[0][0];
int right = matrix[n - 1][n - 1];
while(left < right){
int mid = left + (right - left) / 2;
if(check(matrix, k, mid, n) == false){
left = mid + 1;
}
else{
right = mid;
}
}
return left;
}
public boolean check(int[][]matrix, int k, int mid,int n){
int y = 0;
int x = n - 1;
int count = 0;
while(x >= 0 && y < n){
if(matrix[x][y] <= mid){
count += x + 1;
y++;
}
else{
x--;
}
}
return count >= k;
}
}
Template 2.2
Used to find the right boundary: Pay attention that we need to add one at the end
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
int mid = left + ((right - left) / 2) + 1;
if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid;
}
}
return nums[right] == target ? right : -1;
}
}
Solution for leetcode 34
a combination of finding the left and right boundaries. When we find the right boundary, we start from the previous left boundary. And we deal with the special cases 1) the left boundary is the last position 2) there is only one element that is the same as the target
class Solution {
public int[] searchRange(int[] nums, int target) {
int left = 0;
int[] output = new int[]{-1,-1};
if(nums == null || nums.length == 0) return output;
int right = nums.length - 1;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] < target){
left = mid + 1;
}
else{
right = mid;
}
}
output[0] = nums[left] == target ? left : -1;
if(output[0] != -1){
if(left == nums.length -1 || nums[left + 1] != target){
output[1] = left;
}
else{
right = nums.length - 1;
while(left < right){
int mid = left + (right - left) / 2 + 1;
if(nums[mid] > target){
right = mid - 1;
}
else{
left = mid;
}
}
output[1] = right;
}
}
return output;
}
}
2.3 Find peak element
Solution for leetcode 162
https://leetcode.com/problems/find-peak-element/
class Solution {
public int findPeakElement(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] < nums[mid + 1]){
left = mid + 1;
}
else{
right = mid;
}
}
return left;
}
}