[Leetcode] 280. Wiggle Sort

这一题我最初的想法是通过partitioning将数组分成大小两边,譬如,3,5,1,6,2,4可以变成3, 1, 2, 5, 6, 4。这个过程是可以通过partitioning和 selection ranking algorithm进行实现的。然后左右两边进行交换,左边的位置永远从index 1开始,右边的位置就根据数组的SIZE是奇数还是偶数决定。如果是偶数就是最后一个数字,但如果是奇数就是倒数第二个数字,然后左右交换,每交换一次,左边INDEX往右跳两个,右边INDEX往左跳两个。直到两边指针相遇为止。

    public void swap(int[] nums, int a, int b) {
        if (a != b) {
            nums[a] ^= nums[b];
            nums[b] ^= nums[a];
            nums[a] ^= nums[b];
        }
    }

    public int partition(int[] nums, int head, int tail) {
        int pivot = nums[tail];
        int j = head;
        for (int i = head; i < tail; i++) {
            if (nums[i] <= pivot) {
                swap(nums, i, j);
                j++;
            }
        }
        swap(nums, tail, j);
        return j;
    }

    public void partitionMid(int[] nums) {
        int head = 0, tail = nums.length - 1;
        int mid = nums.length / 2;
        while (head <= tail) {
            int k = partition(nums, head, tail);
            if (k == mid) return;
            else if (k > mid) tail = k - 1;
            else head = k + 1;
        }
    }

    public void wiggleSort(int[] nums) {
        partitionMid(nums);
        int left = 1, right = nums.length % 2 == 0 ? nums.length - 2 : nums.length - 1;
        while (left < right) {
            swap(nums, left, right);
            left += 2;
            right -= 2;
        }
    }

这个解法最坏情况O(N^2),平均是O(N)的,主要是partition带来的复杂度

这题其实还有一个更优解,也非常简单。只需要从左往右扫一次,如果当前INDEX是奇数,那么前面比它大的话就和前面那个数字交换,如果当前INDEX是偶数,那么前面比它小的话就进行交换。就是这么简单....
简单解释一下这种做法的原理的话就是这样的。假如我们有一个数组为arr。

如果arr[1]比arr[0]大的话就符合条件了,arr[1] < arr[0]的话那么arr[1]和arr[0]交换,变成了arr[1], arr[0]....,此时如果arr[2]比arr[0]大的话,就是arr[1] < arr[0] < arr[2]的话,我们再交换arr[0]和arr[2],这个时候arr[2]和arr[0]之间的条件达到了,但是这样主要的问题在于是否会破坏原来arr[1]和arr[0]构造好的关系。但因为arr[2] > arr[0] > arr[1],所以最后还会是arr[1] < arr[2] > arr[0]。往后延续下去也是一样的。根据这个算法,给出以下代码:

    public void swap(int[] nums, int a, int b) {
        if (a != b) {
            nums[a] ^= nums[b];
            nums[b] ^= nums[a];
            nums[a] ^= nums[b];
        }
    }

    public void wiggleSort(int[] nums) {
        for (int i = 1; i < nums.length; ++i) {
            if (i % 2 == 1 && nums[i] < nums[i - 1]) {
                swap(nums, i, i - 1);
            } else if (i % 2 == 0 && nums[i] > nums[i - 1]) {
                swap(nums, i, i - 1);
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/chaochen1407/article/details/82313686
今日推荐