第一部分:四种基本情况
1. 无重复数字的二分查找
leetcode-cn.com/problems/bi…
class Solution {
public int search(int[] nums, int target) {
int n = nums.length;
int l = 0 , r = n-1;
while(l < r){
int mid = l + r + 1 >> 1;
if(nums[mid] > target) r = mid-1;
else l = mid;
}
return nums[l] == target ? l : -1;
}
}
2. 有重复数字的二分查找第一个位置和最后一个位置
leetcode-cn.com/problems/fi…
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = new int[2];
int n = nums.length;
if(n == 0) return new int[]{-1,-1};
int l = 0 , r = n-1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < target) l = mid+1;
else r = mid;
}
if(nums[l] != target) return new int[]{-1,-1};
else res[0] = l;
l = 0;
r = n-1;
while(l < r){
int mid = l + r +1 >> 1;
if(nums[mid] > target) r = mid-1;
else l = mid;
}
res[1] = l;
return res;
}
}
3. 搜索插入位置
leetcode-cn.com/problems/se…
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
if (n == 0 || nums[n-1] < target) return n;
int l = 0 , r = n-1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < target) l = mid + 1;
else r = mid;
}
return l;
}
}
4. x的平方根(只保留整数部分)
class Solution {
public int mySqrt(int x) {
int l = 0 , r = x;
while(l < r){
int mid = l + r + 1 >> 1;
if(mid > x / mid) r = mid-1;
else l = mid;
}
return l;
}
}
5. 寻找重复的数
leetcode-cn.com/problems/fi…
class Solution {
public int findDuplicate(int[] nums) {
int n = nums.length;
int l = 0 , r = n-1;
while (l < r){
int mid = l+r >>1;
int count = 0;
for (int num : nums){
if (num <= mid) count++;
}
if (count > mid) r = mid;
else l = mid+1;
}
return l;
}
}
6. 实现Pow(x,n)
leetcode-cn.com/problems/po…
class Solution {
public double myPow(double x, int n) {
double res = 1.0;
for(int i = n ; i != 0 ; i /=2){
if(i % 2 != 0) res = res * x;
x *= x;
}
return n < 0 ? 1/res : res;
}
}
7. 寻找两个排序数组的中位数
leetcode-cn.com/problems/me…
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
int l = (n + m + 1)/2;
int r = (n + m + 2)/2;
return (getK(nums1, 0 , n-1 , nums2 , 0 , m-1 , l) + getK(nums1 , 0 ,n-1 , nums2 ,0,m-1,r))/2.0;
}
int getK(int[] nums1 , int s1 , int e1 , int[] nums2 , int s2 , int e2 , int k){
int len1 = e1 - s1 + 1;
int len2 = e2 - s2 + 1;
if(len1 > len2) return getK(nums2 , s2 , e2 , nums1 , s1 , e1 , k);
if(len1 == 0) return nums2[s2 + k -1];
if(k == 1) return Math.min(nums1[s1] , nums2[s2]);
int i = s1 + Math.min(len1 , k/2)-1;
int j = s2 + Math.min(len2 , k/2)-1;
if(nums1[i] > nums2[j]) return getK(nums1 , s1 ,e1 , nums2 ,j+1, e2 ,k-(j-s2+1));
else return getK(nums1, i+1 ,e1 , nums2 , s2 , e2 , k-(i-s1+1));
}
}
第二部分:旋转排序数组
1. 寻找旋转排序数组中的最小值(无重复值)
leetcode-cn.com/problems/fi…
class Solution {
public int findMin(int[] nums) {
int n = nums.length;
int l = 0 , r = n-1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] > nums[r]) l = mid+1;
else r = mid;
}
return nums[l];
}
}
2. 寻找旋转排序数组中的最小值(有重复值)
leetcode-cn.com/problems/fi…
class Solution {
public int findMin(int[] nums) {
int n = nums.length;
int l = 0 , r = n-1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] > nums[r]) l = mid+1;
else if(nums[mid] < nums[r]) r = mid;
else r--;
}
return nums[l];
}
}
3. 寻找旋转排序数组中的指定值(无重复值)
leetcode-cn.com/problems/se…
class Solution {
public int search(int[] nums, int target) {
int n = nums.length;
if(n == 0) return -1;
int l = 0 , r = n-1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] > nums[r]){
if(target >= nums[l] && target <= nums[mid]) r = mid;
else l = mid+1;
}else{
if(target > nums[mid] && target <= nums[r]) l = mid+1;
else r = mid;
}
}
return nums[l] == target ? l : -1;
}
}
第三部分:二维矩阵
1. 搜索二维矩阵
leetcode-cn.com/problems/se…
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int l = 0 , r = m *n -1;
while(l < r){
int mid = l + r + 1 >> 1;
if(matrix[mid / n][ mid % n] > target) r = mid-1;
else l = mid;
}
return matrix[l/n][l%n] == target;
}
}
2. 搜索二维矩阵2
leetcode-cn.com/problems/se…
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int i = 0 , j = n-1;
while(i <= m-1 && j >= 0){
if(matrix[i][j] > target) j--;
else if(matrix[i][j] < target) i++;
else return true;
}
return false;
}
}
3. 有序矩阵中第k小的数
leetcode-cn.com/problems/kt…
class Solution {
public int kthSmallest(int[][] matrix, int k) {
int row = matrix.length;
int col = matrix[0].length;
int l = matrix[0][0];
int r = matrix[row-1][col-1];
while(l < r){
int mid = l + r >> 1;
int count = findCount(matrix, mid , row ,col);
if(count < k) l = mid + 1;
else r = mid;
}
return l;
}
int findCount(int[][] matrix , int mid , int row , int col){
int i = row-1 , j = 0;
int count = 0;
while(i >= 0 && j <= col-1){
if(matrix[i][j] <= mid){
count += i+1;
j++;
}else i--;
}
return count;
}
}