摆动排序 II

题目:

 

 

思路:

【1】其实实现交替排序的先决条件便是我们对拿到的无序数组进行有序化,然后采用双指针,一个指向数组头部,一个指向数组尾部,取出数据,以跨度为2的步长,向新数组填充就可以了。时间复杂度 O(nlogn) 空间复杂度 O(n)。

【2】在进阶中要求我们时间复杂度O(N),而且基于数据不会大于5000,所以其实可以考虑使用一个固定长度5000的数组进行存储,记录个数,这样就可以达到一次遍历便可以使得我们使用数据的时候有序了(本质上是基于桶排序的思维),然后依旧是双指针对旧数组进行填充即可。

代码展示:

常规做法:

//克隆一个数组,对其进行排序,将其视为为两个部分, A和B,逆序穿插
class Solution {
    public void wiggleSort(int[] nums) {
        if (nums.length == 0 || nums.length == 1 || nums == null)
            return;
        int[] clone = nums.clone();
        Arrays.sort(clone);

        int n = nums.length;
        int k = n / 2;
        
        int N = n - 1;
        for (int i = 0;i < n - 1; i+=2) {
            nums[i] = clone[N - k];
            nums[i+1] = clone[N];
            N--;
        }
        //奇数的情况下,最后一位没有处理到,需要进行处理
        if (n %2 == 1){
            nums[n - 1] =  clone[0];
        }
        
    }
}

 

基于桶排序的思想:

class Solution {
    public void wiggleSort(int[] nums) {
        int[] bucket = new int[5001];
        for (int num : nums) bucket[num]++;
        int smallIdx, bigIdx, len = nums.length;
        if ((len & 1) == 1){
            smallIdx = len - 1;
            bigIdx = len - 2;
        }else {
            bigIdx = len - 1;
            smallIdx = len - 2;
        }
        int j = 5000;
        for (int i = 1; i <= bigIdx; i += 2) {
            while (bucket[j] == 0) j--;
            nums[i] = j;
            bucket[j]--;
        }
        for (int i = 0; i <= smallIdx; i += 2) {
            while (bucket[j] == 0) j--;
            nums[i] = j;
            bucket[j]--;
        }
    }
}

 

posted @ 2023-01-06 13:21  忧愁的chafry  阅读(28)  评论(0编辑  收藏  举报