• LeetCode 324. Wiggle Sort II


    题目

    这道题目很有意思,有意思的是使用O(n)的时间效率和O(1)的空间效率解决。我会写一篇专业的博客来介绍一下

    以下就是O(n)的时间效率和O(1)的空间效率。

    class Solution {
    public:
    int n;
    int findKth(vector<int>& nums, int s, int e, int k)
    {
        int i = s + 1;
        int j = e;
        int l = s;
        while (i <= j)
        {
            while (i <= j && nums[i] < nums[l])
            {
                i++;
            }
    
            while (i <= j && nums[j] > nums[l])
            {
                j--;
            }
    
            if (i <= j)
            {
                swap(nums[i], nums[j]);
                i++;
                j--;
            }
        }
    
        swap(nums[l], nums[j]);
    
        if (j - l + 1 == k)
            return nums[j];
        else if (j - l + 1 < k)
        {
            return findKth(nums, j + 1, e, k - (j - l + 1));
        }
        else
            return findKth(nums, s, j - 1, k);
    }
    
    double findMid(vector<int>& nums)
    {
        if (nums.size() & 1)
        {
            return findKth(nums, 0, nums.size() - 1, nums.size() / 2 + 1);
        }
        else
        {
            int x = findKth(nums, 0, nums.size() - 1, nums.size() / 2);
            int y = findKth(nums, 0, nums.size() - 1, nums.size() / 2 + 1);
            return 1.0 * (x + y) / 2;
        }
    }
    
    int getNext(int index)
    {
        index -= 2;
        if (index < 0)
        {
            return n + index + (~n & 1) * (~index & 1);
        }
    
        return index;
    }
    
    int getPre(int index)
    {
        index += 2;
    
        if (index >= n)
            return abs((n | 1) - index);
    
        return index;
    }
    
    int compare(int a, int b)
    {
        if ((a ^ b) & 1)
        {
            return a & 1;
        }
        else
        {
            return a <= b;
        }
    }
    
    void wiggleSort(vector<int>& nums) {
    
        if (nums.size() <= 1)
            return;
        double mid = findMid(nums);
        
        int i, j, k;
        n = nums.size();
        i = j = (n & 1 ? n - 1 : n - 2);
        k = 1;
        while (compare(k, j))
        {
            if (nums[j] < mid)
            {
                swap(nums[i], nums[j]);
                i = getNext(i);
                j = getNext(j);
            }
            else if (nums[j] == mid)
            {
                j = getNext(j);
            }
            else
            {
                swap(nums[j], nums[k]);
                k = getPre(k);
            }
        }
    }
    
    };
    
  • 相关阅读:
    BZOJ 1441: Min exgcd
    luogu 1876 开灯 约数+打表
    luogu 1414 又是毕业季II 约数相关
    BZOJ1968: [Ahoi2005]COMMON 约数研究 线性筛
    luogu 3441 [POI2006]MET-Subway 拓扑排序+思维
    Comet OJ
    CF990G GCD Counting 点分治+容斥+暴力
    CF873F Forbidden Indices 后缀自动机+水题
    CF293E Close Vertices 点分治+树状数组
    CF1101D GCD Counting 点分治+质因数分解
  • 原文地址:https://www.cnblogs.com/dacc123/p/13273913.html
Copyright © 2020-2023  润新知