Wiggle Sort II

Total Accepted: 7303 Total Submissions: 33382 Difficulty: Medium
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]....

Example:
(1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].
(2) Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].

Note:
You may assume all input has valid answer.

Follow Up:
Can you do it in O(n) time and/or in-place with O(1) extra space?

思路

  • 法1:直接sort O(nlogn)
  • 法2:先用quick sort找到mid,然后根据mid来赋值,大于mid的放后面,其余的放前面,等于的放中间,然后用3-way partition来O完成
  • 3-way partition就类似于sort color,很棒的思想
public class Solution {
    public void wiggleSort(int[] nums) {
        if (nums == null || nums.length == 0) {
            return;
        }

        int n = nums.length;
        int mid = findMid(nums);
        int start = 0;
        int end = n - 1;
        int midIndex = 0;
        while (midIndex < end) {
            if (nums[midIndex] < mid) {
                swap(nums, midIndex++, start++);
            } else if (nums[midIndex] > mid ) {
                swap(nums, midIndex , end--);
            } else {
                midIndex++;
            }
        }

        int[] temp = new int[n];
        System.arraycopy(nums, 0, temp, 0, n);

        start = (n - 1) / 2;
        end = n - 1;

        for (int i = 0; i < n; i++) {
            if ((i & 1) == 0) {
                nums[i] = temp[start];
                start--;
            } else {
                nums[i] = temp[end];
                end--;
            }
        }
    }

    public int findMid(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int start = 0;
        int end = nums.length - 1;
        int mid = start + (end - start) / 2;
        while (start < end) {
            int k = partition(nums, start, end);

            if (k == mid) {
                return nums[mid];
            } else if (k > mid) {
                end = k - 1;
            } else {
                start = k + 1;
            }
        }
        return nums[mid];
    }

    public int partition(int[] nums, int start, int end) {
        int pivot = nums[start];
        int i = start + 1;
        int j = end;

        while (i <= j) {
            while (i <= j && nums[i] < pivot) {
                i++;
            }
            while (i <= j && nums[j] > pivot) {
                j--;
            }
            if (i > j) {
                break;
            }
            swap(nums, i++, j--);
        }
        swap(nums, start, i - 1);

        return i - 1;
    }

    public void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }
}

results matching ""

    No results matching ""