二分查找
基本的二分查找
leetcode二分查找
注意while循环里面的判断以及边界的取值:
在 int high = arr.length-1; 时候,相当于两端都闭区间 [left, right]
high =mid-1;
while(low <= high)
public static int binary(int [] arr,int num) {
int low =0;
int high = arr.length-1;
while(low<=high) {
int mid =low +(high-low)/2;
if(arr[mid]>num) {
high =mid-1;
}else if(arr[mid]<num) {
low =mid+1;
}else if(arr[mid]==num) {
return mid;
}
}
return -1;
}
如果
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length ;
while(left < right){
int mid = left + (right - left)/2;
if(nums[mid] < target)
left = mid + 1;
else if(nums[mid] > target)
right = mid;
else if(nums[mid] == target)
return mid;
}
return -1;
}
在 int high = arr.length; 时候,相当于左闭右开区间 [left, right)
high =mid;
while(low < high)
左边
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)
left = mid + 1;
else if(nums[mid] > target)
right = mid - 1;
else if(nums[mid] == target)
right = mid - 1;
}
return left;
}
如果不存在返回 -1.
public static int left_bound_fuyi(int [] arr,int num) {
//not find, return -1
int low =0;
int high = arr.length-1;
while(low<=high) {
int mid =low +(high-low)/2;
if(arr[mid]>num) {
high =mid-1;
}else if(arr[mid]<num) {
low =mid+1;
}else if(arr[mid]==num) {
high = mid-1;
}
}
if(low == arr.length)
return -1;
return arr[low]==num?low:-1;
}
右边
如果元素有重复,返回右边的元素,即小于等于它的最大的元素
public static int right_bound1(int [] arr,int num) {
//high = arr.length;
int low =0;
int high = arr.length;
while(low<high) {
int mid =low +(high-low)/2;
if(arr[mid]>num) {
high =mid;
}else if(arr[mid]<num) {
low =mid+1;
}else if(arr[mid]==num) {
low =mid+1;
}
}
return low-1;
}
public static int right_bound(int [] arr,int num) {
//high = arr.length - 1;
int low =0;
int high = arr.length - 1;
while(low <= high) {
int mid =low +(high-low)/2;
if(arr[mid]>num) {
high = mid - 1;
}else if(arr[mid]<num) {
low = mid+1;
}else if(arr[mid]==num) {
low = mid+1;
}
}
return high;//return low - 1;
}
返回 -1
public static int right_bound_fuyi(int [] arr,int num) {
//arr 娑擃厼鐨禍锟� num 閻ㄥ嫬鍘撶槐鐘虫箒 娑擄拷
int low =0;
int high = arr.length;
while(low<high) {
int mid =low +(high-low)/2;
if(arr[mid]>num) {
high =mid;
}else if(arr[mid]<num) {
low =mid+1;
}else if(arr[mid]==num) {
low =mid+1;
}
}
if(low==0) return -1;
return arr[low-1]==num?(low-1):-1;
}
最接近元素的k个值
找到最接近的k个值
1.双指针
public List<Integer> findClosestElement_zhizhen(int[] arr,int k, int x){
int i =0;
int j =arr.length-1;
int len = arr.length;
while(len>k) {
if(Math.abs(arr[i]-x)>Math.abs(arr[j]-x))
i++;
else
j--;
len--;
}
List<Integer> res = new ArrayList<>();
for(int index= i;index<=j;index++) {
res.add(arr[index]);
}
return res;
}
public List<Integer> findClosestElement_binary(int[] arr,int k, int x){
/*
* binarysearch閿涳拷 閹垫儳鍩岀捄婵堫瀲閺堬拷鏉╂垵灏梻瀵告畱鐠ч鍋�
* [mid,mid+k]閸氭啀闂堢姵瀚�
*/
int i =0;
int j =arr.length-k;
while(i<j) {
int mid = i+(j-i)/2;
if(Math.abs(arr[mid]-x)>Math.abs(arr[mid+k]-x))//
i=mid+1;
else
j=mid;
}
List<Integer> res = new ArrayList<>();
for(int index= i;index<i+k;index++) {
res.add(arr[index]);
}
return res;
}
2.二分查找
public List<Integer> findClosestElements(int[] arr, int k, int x) {
int i =0;
int j =arr.length - k - 1;
while(i <= j) {
int mid = i+(j-i)/2;
if(Math.abs(arr[mid]-x)>Math.abs(arr[mid+k]-x))
i=mid+1;
else
j=mid - 1;
}
List<Integer> res = new ArrayList<>();
for(int index= i;index<i+k;index++) {
res.add(arr[index]);
}
return res;
}
有序的二维矩阵
判断是否有某个数
/* 思路
- 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增,
- 因此从左下角开始查找,当要查找数字比左下角数字大时。右移
- 要查找数字比左下角数字小时,上移
*/
public boolean Find(int target,int [][] array) {
int row=0;
int col=array[0].length-1;
while(row<=array.length-1&&col>=0){
if(target==array[row][col])
return true;
else if(target>array[row][col])
row++;
else
col--;
}
return false;
}
第k个数
两层控制:left=right,同时count = k时候输出所求的值
查找小于等于mid的时候,从最后一行的第一列依次查找,同上一个题的思路
class Solution {
public int kthSmallest(int[][] matrix, int k) {
int left = matrix[0][0];
int n = matrix.length;
int right = matrix[n - 1][n - 1];
while(left < right) {
int mid = (left + right)/2;
int count = findCount(matrix, mid);
if(count < k)
left = mid + 1;
else
right = mid;
}
return left;
}
public int findCount(int[][] matrix, int mid) {
int n = matrix.length;
int i = n - 1;
int j = 0;
int count = 0;
//每一列小于等于mid的个数
while(i >= 0 && j < n){
if(matrix[i][j] <= mid) {
count += i + 1;
j ++;
}else {
i --;
}
}
return count;
}
}