LintCode Wiggle Sort II

问题描述:

Given an unsorted array nums, reorder it such that

nums[0] < nums[1] > nums[2] < nums[3]....

Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].

Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].

    分享一种比较直观的解决本题的方法。要使得数组大小交错,很容易想到先排序,再将较小的一半数字放到偶数下标,将较大的一半数字放到奇数下标。问题就会得以解决。

    然而这种方法有一个漏洞。举个例子,测试数组为[1, 2, 2, 3]时,用上述方法求得的解为[1, 2, 2, 3],而正确解为[2, 3, 1, 2]。因此单纯的排序插入并不能解决由于数组重复项造成的问题。针对这种情况,我们可以再添加一步。如果经过上述操作后,若存在重复的项,则从重复项的位置将数组切开,并将前后两部分交换位置,再上述例子中就是将2,3和1,2交换位置,问题得以解决。

代码如下:

public class Solution {
    public void wiggleSort(int[] nums) {
        // Write your code here
        int l = nums.length;
        int i = 0;
        int[] extra = new int[l / 2];
        int[] ano = new int[l];
        int j = 0;
        Arrays.sort(nums);
        for (i = 0; i < l / 2; i++) {
            extra[i] = nums[i + (l + 1) / 2];
        }
        for (i = ((l - 1) / 2) * 2; i >= 0; i--) {
            nums[i] = nums[i / 2];
        }
        for (i = 0; i < l / 2; i++) {
            nums[i * 2 + 1] = extra[i];
        }
        for (i = 0; i < l - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                for (j = 0; j <= i; j++) {
                    ano[j] = nums[j];
                }
                for (j = 0; j < l-i-1; j++) {
                    nums[j] = nums[j + l - i - 1];
                }
                for (j = 0; j <= i; j++) {
                    nums[j + l - i - 1] = ano[j];
                }
            }
        }
    }
}

    本问题中的边界条件的计算比较复杂,需十分仔细。

你可能感兴趣的:(刷题心得)