给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。

    你可以假设所有输入数组都可以得到满足题目要求的结果。

    示例 1:

    输入:nums = [1,5,1,1,6,4]
    输出:[1,6,1,5,1,4]
    解释:[1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。
    示例 2:

    输入:nums = [1,3,2,2,3,1]
    输出:[2,3,1,3,1,2]

    提示:

    1 <= nums.length <= 5 * 104
    0 <= nums[i] <= 5000
    题目数据保证,对于给定的输入 nums ,总能产生满足题目要求的结果

    进阶:你能用 O(n) 时间复杂度和 / 或原地 O(1) 额外空间来实现吗?


    1. class Solution {
    2. /**
    3. 快速选择On找出中位数,然后利用三数排序On将数组排序成三部分,再穿插
    4. */
    5. int[] nums;
    6. int n;
    7. int qselect(int l, int r, int k) {
    8. if (l == r) return nums[l];
    9. int x = nums[l + r >> 1];
    10. int i = l - 1, j = r + 1;
    11. while (i < j) {
    12. do ++i; while (nums[i] < x);
    13. do --j; while (nums[j] > x);
    14. if (i < j) swap(i, j);
    15. }
    16. int cnt = j - l + 1;
    17. if (k <= cnt) return qselect(l, j, k);
    18. else return qselect(j + 1, r, k - cnt);
    19. }
    20. void swap(int i, int j) {
    21. int tem = nums[i];
    22. nums[i] = nums[j];
    23. nums[j] = tem;
    24. }
    25. public void wiggleSort(int[] nums) {
    26. this.nums = nums;
    27. n = nums.length;
    28. // 快速选择找中位数
    29. int mid = qselect(0, n - 1, n + 1 >> 1);
    30. // 让数组变为三段
    31. int l = 0, r = n - 1, loc = 0;
    32. while (loc <= r) {
    33. if (nums[loc] < mid) swap(loc ++, l ++);
    34. else if (nums[loc] > mid) swap(loc, r--);
    35. else loc ++;
    36. }
    37. int[] clone = nums.clone();
    38. int idx = 1; loc = n - 1;
    39. while (idx < n) {
    40. nums[idx] = clone[loc--];
    41. idx += 2;
    42. }
    43. idx = 0;
    44. while (idx < n) {
    45. nums[idx] = clone[loc--];
    46. idx += 2;
    47. }
    48. }
    49. }