0
点赞
收藏
分享

微信扫一扫

算法专练:排序

是她丫 2022-05-03 阅读 48

文章目录

1.977. 有序数组的平方

原题链接

不追求很高的时间复杂度的化我们就对数组进行原地修改并排序即可。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for(int i=0;i<nums.size();i++){
            nums[i]*=nums[i];
        }
        sort(nums.begin(),nums.end());
        return nums;
    }
};

2.268. 丢失的数字

原题链接

        使用排序的做法非常简单,对原数组进行排序然后对照下标即可,因为数组中的数组是从[0,n]排序之后找到第一个与下标不等的元素返回即可。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++){
            if(i!=nums[i]){
                return i;
            }
        }
        return nums.size();
    }
};

        当然也有更优的时间复杂度,又观察到题目告诉我们数组元素均是独一无二的,那么我们就可以先算出[0,n]这些数字的和,然后减去数组中元素和,那么剩下的就是缺失的元素。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        int sum=(1+n)*n/2;
        for(int i=0;i<n;i++){
            sum-=nums[i];
        }
        return sum;
    }
};

3.1877. 数组中最大数对和的最小值

原题链接

        这道题更像是贪心,不过我们的贪心策略就是利用排序。题目要求我们找出最小的最大数对和,那么如何找到最大数对和?很简单,将数组划分为若干数对之后找出最大值就行,对于这个过程如果没有要求我们找出最小的最大数对和,完全可以吧数组最大和第二大元素相加并返回。但问题是如何找到最小的最大数对和。
        首先最小的最大数对和就是指吧数组中的配对情况都列出后我们返回最小的最大数对和。我们先满足最小,这就很简单了,要想使得数对和最小,我们吧数组进行升序排序,再不断遍历让当前遍历到的较大元素加上较小元素即可,并不断维护最大值。至于为何这样是最小的数对和可以利用基本不等式证明,这里就不再解释了。

class Solution {
public:
    int minPairSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int ans=0;
        for(int i=0;i<nums.size()/2;++i){
            ans=max(ans,nums[i]+nums[nums.size()-i-1]);
        }
        return ans;
    }
};

4.950. 按递增顺序显示卡牌

原题链接

        这道题刚开始读起来是十分饶的,其实题目要让我们求的就是一个按照他要求的规则拿牌之后拿到的是一个递增顺序的顺序序列。对比示例并且按照他的规则拿牌即可看出。
        但是直接找到这样一个序列肯定是十分麻烦的,我们转换一下思路。假如现在我们的序列就是一个升序的序列,也就是按照答案和规则拿到的序列,我们要做的就是找到它是由哪个序列拿到的即可,听上去是不是跟之前的思路没什么两样,但是这却是十分简单的思路。
        首先我们将数组进行升序排序,并且定义一个记录原始下标的位置。然后对下标数组按规则进行拿牌。之后我们得到了新的下标数组:tmp,接下来你可能会问这一步的意义是什么。
        首先我们要明白一点,对下标数组进行按规则拿牌是针对所有的顺序的并不是单一的原数组顺序或者是答案顺序,也就是说任何一个数组按照这个规则拿牌之后他所对应的下标数组就是我们的tmp数组.自然而然的对于答案数组,按照所得到的tmp数组映射就是升序序列。这是一个双射的关系,可以互相映射。
        现在我们假设我们拿牌的牌组就是答案数组,接下来要做的就是对这个答案数组按照规则拿完牌之后的序列也就是我们的升序序列按照下标关系映射回去即可.

class Solution {
public:
    vector<int> deckRevealedIncreasing(vector<int>& deck) {
        vector<int> ans,index,tmp;
        for(int i=0;i<deck.size();i++){
            index.push_back(i);
        }
        sort(deck.begin(),deck.end());
        int l=0,r=deck.size()-1;
        while(l<=r){
            tmp.push_back(index[l]);
            l++;
            if(l>r){
                break;
            }
            index.push_back(index[l]);
            r++;
            l++;
        }
        for(int i=0;i<deck.size();i++){
            ans.push_back(0);
        }
        for(int i=0;i<deck.size();i++){
            ans[tmp[i]]=deck[i];
        }
        return ans;
    }
};
举报

相关推荐

0 条评论