当前位置:   article > 正文

剑指Offer面试题8旋转数组的最小数字(二分查找)附带快排和按年龄排序

剑指Offer面试题8旋转数组的最小数字(二分查找)附带快排和按年龄排序

面试题8:旋转数组的最小数字

把一个数组最开始的几个元素搬到数组末尾,我们称之为数组的旋转,输入一个递增的数组的旋转,输出它的最小元素。如{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,输出1。

思路:直观想法是从头到尾遍历就行,复杂度O(n),但是这个数组其实已经划分为两个排好序的子数组,前面一个子数组的元素都大于等于后边一个,并以最小元素为分界。

对于排好序的数组,推荐用二分查找复杂度为O(logn),做法是一个指针指首元素,一个指针指尾元素,若中间元素大于等于首元素,则它位于前一个子数组内,最小元素在中间元素之后。反之同理。

用二分方法处理此问题:

  1. public class Min {
  2. //最简单的二分
  3. static Integer printMin(int array[]) {
  4. int low = 0 ;
  5. int high = array.length - 1;
  6. if(array.length == 0) return null;//判空
  7. while(low < high){
  8. int mid = (low + high)/2;
  9. if(array[mid] > array[high]){
  10. low = mid + 1;
  11. }else if(array[mid] == array[high]){
  12. high = high - 1;
  13. }else{
  14. high = mid;
  15. }
  16. }
  17. return array[low];
  18. }
  19. public static void main(String[] args) {
  20. int test[] = {3,4,5,1,2};//{2,2,2,1,2}
  21. System.out.println(printMin(test));
  22. }
  23. }

快排的写法要很熟练:

  1. import java.util.Arrays;
  2. public class QSort {
  3. //快排
  4. private void qsort(int a[],int left,int right){
  5. if(a.length == 0) System.out.println("输入为空");
  6. if(left >= right) return;//代表快排完成一轮了
  7. int i = left;
  8. int j = right;
  9. int key = a[left];//以第一个元素为参照key
  10. while(i < j){
  11. while(i < j && key <= a[j]){
  12. j--;//从后往前找比key小的
  13. }
  14. a[i] = a[j];//把找到的比key小的数往前挪
  15. while(i < j && key >= a[i]){
  16. i++;//从前往后找比key大的值
  17. }
  18. a[j] = a[i];//把找到的比key大的数往后挪
  19. }
  20. //排完一轮后把参照key还原,现在a[i]是分界线,对左右两边递归
  21. a[i] = key;
  22. qsort(a,left,i-1);
  23. qsort(a,i+1,right);
  24. }
  25. public static void main(String[] args) {
  26. QSort test = new QSort();
  27. int array[] = {5,4,2,3,1};
  28. test.qsort(array,0,array.length-1);
  29. System.out.println(Arrays.toString(array));
  30. }
  31. }

对员工按年龄进行排序的问题:

  1. import java.util.Arrays;
  2. public class SortAges {
  3. //按所有员工的年龄进行排序,要求复杂度O(n)。
  4. //此题特点是所有的数字大小在一个小范围内(年龄在0-99,使用辅助空间)
  5. private void sortAges(int ages[]){
  6. if(ages.length == 0) System.out.println("输入为空");
  7. int oldestAge = 99;//最大年龄99
  8. int timesOfAge[] = new int[oldestAge+1];//保存每个年龄出现的次数
  9. for(int i=0;i<=oldestAge;i++){
  10. timesOfAge[i] = 0;//初始化为0
  11. }
  12. for(int i=0;i<ages.length;i++){
  13. if(ages[i] < 0 || ages[i] > oldestAge){
  14. System.out.println("错误,年龄越界");
  15. return;
  16. }else{
  17. timesOfAge[ages[i]]++;//该年龄出现次数加1
  18. }
  19. }
  20. //开始按年龄排序
  21. int index = 0;
  22. for(int i=0;i<=oldestAge;i++){
  23. for(int j=0;j<timesOfAge[i];j++){
  24. ages[index] = i;
  25. index++;
  26. }
  27. }
  28. }
  29. public static void main(String[] args) {
  30. SortAges test = new SortAges();
  31. int a[] = {14,25,22,44,29,44,88};//输入所有员工的年龄
  32. test.sortAges(a);
  33. System.out.println(Arrays.toString(a));
  34. }
  35. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/43635
推荐阅读
相关标签
  

闽ICP备14008679号