本文已参与「新人创作礼」活动,一起开启掘金创作之路
4.二分查找
(1) 最简单的二分查找
最简单的二分查找是在升序序列里查找给定val是否存在该序列中,该算法只能找出该val是否存在于序列中,而无法找出序列有多少个val。代码如下:
public static int search(int[] nums,int val){
int l = 0;
int r = nums.length;
while(l <= r){
int mid = l + r >> 1;
if(nums[mid] == val)
return mid;
else if(nums[mid] < val)
l = mid + 1;
else
r = mid - 1;
}
return -1;
}
(2)二分查找改-1
二分查找第一个大于等于X的最小值(如TreeMap里的ceilingKey)
若需要对已经排好序的数字序列进行插入操作,需要找到能插入的位置,我们应该怎么办呢?对二分查找进行修改即可
public static int search(int[] nums,int x){
int l = 0;
int r = nums.length - 1;
while(l < r){
int mid = l + r >> 1;
//如果val比中间的值大,则可以直接跳过,左区间可以直接忽略,跳到mid + 1;
if(nums[mid] < val){
l = mid + 1;
}else{
//如果val比中间值小于或等于,则将r进行缩减,而不是直接r = mid - 1;
r = mid;
}
}
return l;
}
(3)二分查找改-2
二分查找一个小于等于X的最大值(如TreeMap中的floorKey)
public static int search(int[] nums,int x){
int l = 0;
int r = nums.length - 1;
int ans = 0;
while(l <= r){
int mid = l + (r - l >> 1);
if(nums[mid] > x){
r = mid - 1;
}else{
ans = mid;
l = mid + 1;
}
}
return ans;
}
5.归并排序
归并排序的思想也是分治思想,归并排序的时间复杂度为O(nlogn),暂时还没深入了解
归并排序类似快速排序一样的将数组进行二分,直到分到剩余单独的一个个体,也就是分不了的状态,然后重新进行合并。
int[] brr = new int[arr.length];
public static void mergerSort(int[] arr,int l,int r){
if(l >= r) return ;
int mid = l + r >> 1;
//分
mergerSort(arr,l,mid);
mergerSort(arr,mid + 1,r);
//合
int i,j,k = l;
for(i = l, j = mid + 1, i <= mid && j <= r){
if(arr[i] > arr[j]){
brr[k++] = arr[j++];
}else{
brr[k++] = arr[i++];
}
}
while(i <= mid) brr[k++] = arr[i++];
while(j <= r) brr[k++] = arr[j++];
for(i = l; i <= r; i++){
arr[i] = brr[i];
}
}
\