324. Wiggle Sort II

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?

此题难度系数很高,和Kth Largest Element in an Array有点关系,通过前一道题来求出中位数,然后遍历数组,大于中位数的数组值排在索引为奇数的位置(1,3,5...),小于中位数的数组值排在偶数的位置(...10,8,6,4,2,0),将数组值等于中位数的值不变化(现在不理解这部分),代码如下:

public class Solution {

    public void wiggleSort(int[] nums) {

        int n = nums.length;

        int mid = findKthlargest(nums,(n+1)/2);

        int left = 0;

        int right = nums.length-1;

        int i = 0;

        while(i<=right){

            if(nums[newIndex(i,n)]>mid) swap(nums,newIndex(i++,n),newIndex(left++,n));

            else if(nums[newIndex(i,n)]<mid) swap(nums,newIndex(i,n),newIndex(right--,n));

            else i++;

        }

        

    }

    public int findKthlargest(int[] nums,int k){

        int n = nums.length;

        int p = quickselect(nums,0,n-1,n-k+1);

        return nums[p];

    }

    public int quickselect(int[] nums,int lo,int hi,int k){

        int i = lo;

        int j = hi;

        int pivot = nums[hi];

        while(i<j){

            if(nums[i++]>pivot) swap(nums,--i,--j);

        }

        swap(nums,i,hi);

        int order = i-lo+1;

        if(order==k) return i;

        else if(order>k) return quickselect(nums,lo,i-1,k);

        else return quickselect(nums,i+1,hi,k-order);

    }

    public void swap(int[] nums,int i,int j){

        int temp = nums[i];

        nums[i] = nums[j];

        nums[j] = temp;

    }

    public int newIndex(int idx,int n){

        return (1+2*idx)%(n|1);

    }

    

}

详细的讲解在链接处:

https://discuss.leetcode.com/topic/41464/step-by-step-explanation-of-index-mapping-in-java

原文地址:https://www.cnblogs.com/codeskiller/p/6360926.html