百度笔试题:一个已经排序好的很大的数组,现在给它划分成m段,每段长度不定,段长最长为k,然后段内打乱顺序,请设计一个算法对其进行重新排序

来源:互联网 发布:唐朝 阿拉伯 知乎 编辑:程序博客网 时间:2024/05/16 08:33
Java代码 复制代码 收藏代码
  1. import java.util.Arrays;
  2. /**
  3. * 最早是在陈利人老师的微博看到这道题:
  4. * #面试题#An array with n elements which is K most sorted,就是每个element的初始位置和它最终的排序后的位置的距离不超过常数K
  5. * 设计一个排序算法。It should be faster than O(n*lgn)。
  6. *
  7. * 英文原题是:
  8. * Given an array of n elements, where each element is at most k away from its target position, devise an algorithm that sorts in O(n log k) time.
  9. * For example, let us consider k is 2, an element at index 7 in the sorted array, can be at indexes 5, 6, 7, 8, 9 in the given array.
  10. *
  11. * 微博里面的回复提到这道题的另一个表述:
  12. * @castomer:回复@华仔陶陶:今年百度校园招聘笔试题目我遇到了一道题和这个基本一样。“
  13. * 一个已经排序好的很大的数组,现在给它划分成m段,每段长度不定,段长最长为k,然后段内打乱顺序,请设计一个算法对其进行重新排序”
  14. *
  15. * 两种解法:
  16. * 1、插入排序,时间复杂度是O(n*k)
  17. * 由于“K most sorted”,寻找位置时最多只会寻找k位,因此复杂度从最坏情况的O(n*n)下降到O(n*k), 但插入排序没有充分利用“K most sorted”这个条件
  18. * 2、最小堆
  19. * @castomer 认为堆的大小是k
  20. * 这要看k most sorted怎么理解了
  21. * 例如,如果对于{4, 3, 2, 1}认为k=3,那么堆的大小就应该是4。因为如果取3的话,第一次最小堆{2, 3, 4}排序后取出最小值2,第二次最小堆排序后取出最小值1,2排在1前面,显然不合理
  22. *
  23. * 最小堆的时间复杂度是O(k) + (n-k) * O(lgk):
  24. * 建堆:O(k),k为堆的大小
  25. * 堆排序:(n-k) * O(lgk)
  26. *
  27. */
  28. public class KSortedArray {
  29. public static void main(String[] args) {
  30. int k = 3;
  31. int[] array = {2, 6, 3, 12, 56, 8};
  32. insertSort(array);
  33. minHeapSort(array, k);
  34. }
  35. public static void insertSort(int[] arrayToSort) {
  36. //...略去输入合法性检查
  37. //复制数组,不影响原数组
  38. int len = arrayToSort.length;
  39. int[] array = new int[len];
  40. System.arraycopy(arrayToSort, 0, array, 0, len);
  41. for (int i = 1; i < len; i++) {
  42. int itemToInsert = array[i];
  43. while(i > 0 && itemToInsert < array[i -1]) {
  44. array[i] = array[i - 1];
  45. i--;
  46. }
  47. array[i] = itemToInsert;
  48. }
  49. System.out.println(Arrays.toString(array));
  50. }
原创粉丝点击