剑指Offer面试题8旋转数组的最小数字(二分查找)附带快排和按年龄排序
2017-03-02 18:11
706 查看
面试题8:旋转数组的最小数字
把一个数组最开始的几个元素搬到数组末尾,我们称之为数组的旋转,输入一个递增的数组的旋转,输出它的最小元素。如{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,输出1。思路:直观想法是从头到尾遍历就行,复杂度O(n),但是这个数组其实已经划分为两个排好序的子数组,前面一个子数组的元素都大于等于后边一个,并以最小元素为分界。
对于排好序的数组,推荐用二分查找复杂度为O(logn),做法是一个指针指首元素,一个指针指尾元素,若中间元素大于等于首元素,则它位于前一个子数组内,最小元素在中间元素之后。反之同理。
用二分方法处理此问题:
public class Min {//最简单的二分
static Integer printMin(int array[]) {
int low = 0 ;
int high = array.length - 1;
if(array.length == 0) return null;//判空
while(low < high){
int mid = (low + high)/2;
if(array[mid] > array[high]){
low = mid + 1;
}else if(array[mid] == array[high]){
high = high - 1;
}else{
high = mid;
}
}
return array[low];
}
public static void main(String[] args) {
int test[] = {3,4,5,1,2};//{2,2,2,1,2}
System.out.println(printMin(test));
}
}
快排的写法要很熟练:
import java.util.Arrays; public class QSort { //快排 private void qsort(int a[],int left,int right){ if(a.length == 0) System.out.println("输入为空"); if(left >= right) return;//代表快排完成一轮了 int i = left; int j = right; int key = a[left];//以第一个元素为参照key while(i < j){ while(i < j && key <= a[j]){ j--;//从后往前找比key小的 } a[i] = a[j];//把找到的比key小的数往前挪 while(i < j && key >= a[i]){ i++;//从前往后找比key大的值 } a[j] = a[i];//把找到的比key大的数往后挪 } //排完一轮后把参照key还原,现在a[i]是分界线,对左右两边递归 a[i] = key; qsort(a,left,i-1); qsort(a,i+1,right); } public static void main(String[] args) { QSort test = new QSort(); int array[] = {5,4,2,3,1}; test.qsort(array,0,array.length-1); System.out.println(Arrays.toString(array)); } }
对员工按年龄进行排序的问题:
import java.util.Arrays;public class SortAges {
//按所有员工的年龄进行排序,要求复杂度O(n)。
//此题特点是所有的数字大小在一个小范围内(年龄在0-99,使用辅助空间)
private void sortAges(int ages[]){
if(ages.length == 0) System.out.println("输入为空");
int oldestAge = 99;//最大年龄99
int timesOfAge[] = new int[oldestAge+1];//保存每个年龄出现的次数
for(int i=0;i<=oldestAge;i++){
timesOfAge[i] = 0;//初始化为0
}
for(int i=0;i<ages.length;i++){
if(ages[i] < 0 || ages[i] > oldestAge){
System.out.println("错误,年龄越界");
return;
}else{
timesOfAge[ages[i]]++;//该年龄出现次数加1
}
}
//开始按年龄排序
int index = 0;
for(int i=0;i<=oldestAge;i++){
for(int j=0;j<timesOfAge[i];j++){
ages[index] = i;
index++;
}
}
}
public static void main(String[] args) {
SortAges test = new SortAges();
int a[] = {14,25,22,44,29,44,88};//输入所有员工的年龄
test.sortAges(a);
System.out.println(Arrays.toString(a));
}
}
相关文章推荐
- 【剑指offer】2.4.1查找和排序——面试题8:旋转数组的最小数字
- 剑指offer--面试题53 在排序数组中查找数字(二分)
- 【剑指offer】【旋转数组的最小数字 】二分查找的变体
- 剑指offer 8题 【查找和排序 】旋转数组的最小数字
- 【剑指offer】旋转数组的最小数字&&二分查找
- 剑指offer 面试题8—旋转数组的最小数字
- 剑指Offer---面试题8:旋转数组的最小数字
- 【剑指offer】面试题8:旋转数组的最小数字
- 剑指offer面试题8:旋转数组的最小数字
- 旋转数组的最小数字(剑指offer 二分 O(log n))
- 【剑指Offer学习】【面试题8 : 旋转数组的最小数字】
- 旋转数组的最小数字(剑指offer面试题)
- 剑指offer-面试题8 旋转数组的最小数字
- 剑指offer面试题 旋转数组的最小数字
- 【剑指offer】面试题8:旋转数组中的最小数字
- 剑指offer面试题8:旋转数组的最小数字
- 剑指offer-面试题8:旋转数组中的最小数字
- 码农小汪剑指Offer之35-数字在排序数组中出现的次数 暴力 二分查找的运用
- 【剑指Offer面试题】 九度OJ1386:旋转数组的最小数字
- 剑指offer之面试题8:旋转数组的最小数字