查找:顺序查找,二分查找,哈希表查找,二叉排序树查找。
哈希表和二叉排序树考察重点在于数据结构而不是算法
哈希表的主要优点是我们利用他能够在O(1)时间内查到某一元素,是效率最高的查找方式:但是缺点是需要额外的空间来实现哈希表。
二叉排序树查找算法对应的数据结构是二叉搜索树
排序比查找要复杂一些。比较插入、冒泡、归并、快速等不同排序算法的优劣
快速排序
public class quickSort {
public static void println(int[] num){
for(int i=0;i<num.length;i++){
System.out.println(num[i]);
}
}
//快速排序
public static void quick_sort(int s[], int l, int r) {
if (l < r) {
int i = l, j = r, x = s[l];
while (i < j) {
while(i < j && s[j] >= x) {
// 从右向左找第一个小于x的数
j--;
}
if(i < j){
s[i++] = s[j];
}
while(i < j && s[i] < x){
// 从左向右找第一个大于等于x的数
i++;
}
if(i < j){
s[j--] = s[i];
}
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
public static void main(String[] args){
int[] num={10,9,8,7,6,5,4,3,2,1};
quick_sort(num,0,9);
println(num);
}
}
面试题11.旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的的一个旋转,输出旋转数组的最小元素,例如{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1
最简思路:从头到尾遍历一遍数组O(n),找到最小的元素但是达不到面试官的期待
旋转之后的数组可以划分为两个排序的子数组,而且前面子数组的元素都大于或等于后面子数组的元素。我们还注意到最小的元素刚好是这两个子数组的分界线。在排序的数组中我们可以用二分查找O(logn)来寻找最小元素
{3,4,5,1,2},先把第一个指针指向第0个元素,把第二个指针指向最后一个元素,位于两个指针中间的数字是5,他大于第一个指针指向的数字,因此中间数字5一定是第一个数组的,而最小数字一定位于他的后面,因此移动第一个指针,让他指向数组的中位数,此时两个指针的中间数是1,小于第二个指针指向的数字,因此1是第二个数组的元素,移动第二个指针指向1,这时,两个指针已经紧挨着了,因此第二个指针指向最小值
然后考虑边界条件补充这些情况
public class minValArray {
public static int minValArray(int[] num){
int length=num.length;
//当数组元素为空
if(num.length<=0){
System.out.println("Invalid Array");
return -1;
}
int p1=0,p2=length-1;
int res=p1;
//当左指针大于右指针
while(num[p1]>num[p2]){
if(p1+1==p2){
res=p2;
break;
}
int mid=(p1+p2)/2;
if(num[mid]>num[p1]){
p1=mid;
}
if(num[mid]<=num[p2]){
p2=mid;
}
}
//当左指针等于右指针
if(num[p1]==num[p2]){
for(int i=1;i<length;i++){
if(num[res]>num[i]){
res=i;
}
}
}
return num[res];
}
public static void main(String[] args){
int[] num=new int[]{3,4,5,1,2};
int[] num2=new int[]{1,2,3,4,5};
int[] num3=new int[]{1,0,1,1,1};
int[] num4=new int[]{};
int[] num5=new int[]{1,2,2,0,0};
System.out.println(minValArray(num5));
}
}