• [LeetCode] 324. Wiggle Sort II 摆动排序 II


    Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]....

    Example 1:

    Input: nums = [1, 5, 1, 1, 6, 4]
    Output: One possible answer is [1, 4, 1, 5, 1, 6].

    Example 2:

    Input: nums = [1, 3, 2, 2, 3, 1]
    Output: 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?

    280. Wiggle Sort 的变形,这题nums[0] < nums[1] > nums[2] < nums[3]....里面没有等号。 

    解法1:先对数组进行排序, 然后从左往右奇数索引位置放大于中位数的数, 然后从右往左在偶数索引位置放小于中位数的数, 剩下的位置都放中位数. 其T: O(nlog(n)), S: O(n).

    解法2:利用quickSelect算法,从未经排序的数组nums中选出中位数mid,以中位数mid为界,将大于mid的元素排列在ix的较小部分,而将小于mid的元素排列在ix的较大部分。T: O(n), S: O(1)

    解法3:three-way partitioning,variant of 75. Sort Colors 

    Java:

    public void wiggleSort(int[] nums) {
            int median = findKthLargest(nums, (nums.length + 1) / 2);
            int n = nums.length;
    
            int left = 0, i = 0, right = n - 1;
    
            while (i <= right) {
    
                if (nums[newIndex(i,n)] > median) {
                    swap(nums, newIndex(left++,n), newIndex(i++,n));
                }
                else if (nums[newIndex(i,n)] < median) {
                    swap(nums, newIndex(right--,n), newIndex(i,n));
                }
                else {
                    i++;
                }
            }
    
    
        }
    
        private int newIndex(int index, int n) {
            return (1 + 2*index) % (n | 1);
        }
    

    Java:

    void wiggleSort(vector<int>& nums) {
        int n = nums.size();
        
        // Find a median.
        auto midptr = nums.begin() + n / 2;
        nth_element(nums.begin(), midptr, nums.end());
        int mid = *midptr;
        
        // Index-rewiring.
        #define A(i) nums[(1+2*(i)) % (n|1)]
    
        // 3-way-partition-to-wiggly in O(n) time with O(1) space.
        int i = 0, j = 0, k = n - 1;
        while (j <= k) {
            if (A(j) > mid)
                swap(A(i++), A(j++));
            else if (A(j) < mid)
                swap(A(j), A(k--));
            else
                j++;
        }
    }
    

    Java:

    public class Solution {
        public void wiggleSort(int[] nums) {
            int medium = findMedium(nums, 0, nums.length - 1, (nums.length + 1) >> 1);
            int s = 0, t = nums.length - 1 , mid_index = (nums.length + 1) >> 1;
            int[] temp = new int[nums.length];
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] < medium)
                    temp[s++] = nums[i];
                else if (nums[i] > medium)
                    temp[t--] = nums[i];
            }
     
            while (s < mid_index) temp[s++] = medium;
            while (t >= mid_index) temp[t--] = medium;
     
            t = nums.length;
            for (int i = 0; i < nums.length; i++)
                nums[i] = (i & 1) == 0 ? temp[--s] : temp[--t];
        }
     
        private int findMedium(int[] nums, int L, int R, int k) {
            if (L >= R) return nums[R];
            int i = partition(nums, L, R);
            int cnt = i - L + 1;
            if (cnt == k) return nums[i];
            return cnt > k ? findMedium(nums, L, i - 1, k) : findMedium(nums, i + 1, R, k - cnt);
        }
     
        private int partition(int[] nums, int L, int R) {
            int val = nums[L];
            int i = L, j = R + 1;
            while (true) {
                while (++i < R && nums[i] < val) ;
                while (--j > L && nums[j] > val) ;
                if (i >= j) break;
                swap(nums, i, j);
            }
            swap(nums, L, j);
            return j;
        }
     
        private void swap(int[] nums, int i, int j) {
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }  

    Python:

    # Time:  O(nlogn)
    # Space: O(n)
    # Sorting and reoder solution. (92ms)
    class Solution(object):
        def wiggleSort(self, nums):
            """
            :type nums: List[int]
            :rtype: void Do not return anything, modify nums in-place instead.
            """
            nums.sort()
            med = (len(nums) - 1) / 2
            nums[::2], nums[1::2] = nums[med::-1], nums[:med:-1]  

    Python:

    # Time:  O(n) ~ O(n^2)
    # Space: O(1)
    # Tri Partition (aka Dutch National Flag Problem) with virtual index solution. (TLE)
    from random import randint
    class Solution2(object):
        def wiggleSort(self, nums):
            """
            :type nums: List[int]
            :rtype: void Do not return anything, modify nums in-place instead.
            """
            def findKthLargest(nums, k):
                left, right = 0, len(nums) - 1
                while left <= right:
                    pivot_idx = randint(left, right)
                    new_pivot_idx = partitionAroundPivot(left, right, pivot_idx, nums)
                    if new_pivot_idx == k - 1:
                        return nums[new_pivot_idx]
                    elif new_pivot_idx > k - 1:
                        right = new_pivot_idx - 1
                    else:  # new_pivot_idx < k - 1.
                        left = new_pivot_idx + 1
    
            def partitionAroundPivot(left, right, pivot_idx, nums):
                pivot_value = nums[pivot_idx]
                new_pivot_idx = left
                nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
                for i in xrange(left, right):
                    if nums[i] > pivot_value:
                        nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i]
                        new_pivot_idx += 1
                nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right]
                return new_pivot_idx
    
            def reversedTriPartitionWithVI(nums, val):
                def idx(i, N):
                    return (1 + 2 * (i)) % N
    
                N = len(nums) / 2 * 2 + 1
                i, j, n = 0, 0, len(nums) - 1
                while j <= n:
                    if nums[idx(j, N)] > val:
                        nums[idx(i, N)], nums[idx(j, N)] = nums[idx(j, N)], nums[idx(i, N)]
                        i += 1
                        j += 1
                    elif nums[idx(j, N)] < val:
                        nums[idx(j, N)], nums[idx(n, N)] = nums[idx(n, N)], nums[idx(j, N)]
                        n -= 1
                    else:
                        j += 1
    
            mid = (len(nums) - 1) / 2
            findKthLargest(nums, mid + 1)
            reversedTriPartitionWithVI(nums, nums[mid])

    C++:

    // O(n) space
    class Solution {
    public:
        void wiggleSort(vector<int>& nums) {
            vector<int> tmp = nums;
            int n = nums.size(), k = (n + 1) / 2, j = n; 
            sort(tmp.begin(), tmp.end());
            for (int i = 0; i < n; ++i) {
                nums[i] = i & 1 ? tmp[--j] : tmp[--k];
            }
        }
    };  

    C++:

    // O(1) space
    class Solution {
    public:
        void wiggleSort(vector<int>& nums) {
            #define A(i) nums[(1 + 2 * i) % (n | 1)]
            int n = nums.size(), i = 0, j = 0, k = n - 1;
            auto midptr = nums.begin() + n / 2;
            nth_element(nums.begin(), midptr, nums.end());
            int mid = *midptr;
            while (j <= k) {
                if (A(j) > mid) swap(A(i++), A(j++));
                else if (A(j) < mid) swap(A(j), A(k--));
                else ++j;
            }
        }
    };
    

      

    类似题目:

    [LeetCode] 280. Wiggle Sort 摆动排序

    [LeetCode] 75. Sort Colors 颜色排序

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    微信小程序如何获取openid
    js经典试题之常用的方法
    js经典试题之运算符的优先级
    js如何使浏览器允许脚本异步加载
    es6从零学习(五):Module的语法
    es6从零学习(四):Class的继承
    js如何处理字符串中带有↵字符
    Zuul中聚合Swagger的坑
    阿里Sentinel支持Spring Cloud Gateway啦
    Spring Boot中的Mongodb多数据源扩展
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9771952.html
Copyright © 2020-2023  润新知