Byte提前批二面中自己在二分查找的变形题中翻了车,导致现在还不知道面试是否会通过,面试结束后真的感觉无法原谅自己在这么简单的问题上翻车。本以为自己在算法的准备上还算充分,原来是自己好高骛远了,一直在看相对比较难的算法,而没有踏踏实实熟练掌握基础算法。从实习到面试,整个七月里一直被反复教做人 ,踏踏实实学习吧。 |
---|
1 二分查找及其应用
二分查找的基本思想(二叉搜索树也应该算是二分查找的范畴)
二分查找的基本思想是:(设R[low,high]是当前的查找区间)
(1) 首先确定该区间的中点位置:
(2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
①若R[mid].key>K,则由表的有序性可知R[mid,n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1,mid-1]中,故新的查找区间是左子表R[1,mid-1]。
②类似地,若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1,n]中,即新的查找区间是右子表R[mid+1,n]。下一次查找是针对新的查找区间进行的。
因此,从初始的查找区间R[1,n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。
二分查找的应用
数组中找到局部最小的值
数字在排序数组中出现的次数
在有序旋转数组中找到最小值
在有序旋转数组中找到一个数
最小的k个数-这里partaton与二分结合的方法时间复杂度和空间复杂度最优
2 快排及其应用
刷题的过程中发现,排序算法中快排、堆排和归并思想使用得最多,
选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴,也是初始的坑位。
设置两个变量left = 0;right = N - 1;
从left一直向后走,直到找到一个大于key的值,然后将该数放入坑中,坑位变成了array[left]。
right一直向前走,直到找到一个小于key的值,然后将该数放入坑中,坑位变成了array[right]。
重复3和4的步骤,直到left和right相遇,然后将key放入最后一个坑位。
class Solution {
public int[] sortArray(int[] nums) {
int left=0;
int right=nums.length-1;
quickSort(nums,left,right);
return nums;
}
public void quickSort(int[] array,int left,int right){
if(left >= right)//表示已经完成一个组
{
return;
}
int index = partation(array,left,right);//枢轴的位置
quickSort(array,left,index - 1);
quickSort(array,index + 1,right);
}
public int partation(int[] array,int left,int right){
int key = array[right];
while(left < right) {
while(left < right && array[left] <= key)
{
++left;
}
array[right] = array[left];
while(left < right && array[right] >= key)
{
--right;
}
array[left] = array[right];
}
array[right] = key;
return left;
}
}
快排的应用(其实就是partation的应用)
经典荷兰国旗问题
3堆排及应用
堆是一种数据结构,一种叫做完全二叉树的数据结构。大顶堆:每个节点的值都大于或者等于它的左右子节点的值。小顶堆:每个节点的值都小于或者等于它的左右子节点的值。对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
,对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]。
堆排序的基本思想是:1、将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;2、将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆;3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。最后,就得到一个有序的序列了。
import java.util.*;
class Solution {
public int[] sortArray(int[] nums) {
// Arrays.sort(nums);
heapSort(nums);
return nums;
}
public void heapSort(int[] arr