优势洗牌&&括号的分数

89 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

[870. 优势洗牌]

leetcode.cn/problems/ad…

image-20221008201247251

本题结果数组要满足ret[i] > nums2[i]的个数最多, 本质是田径赛马问题!讨论田忌的下等马(nums1的最小值):

  • 如果它能比过齐威王的下等马(nums2的最小值),那这一分田忌直接拿下
  • 如果它比不过齐威王的下等马,则用田忌的下等马比齐威王的上等马(nums2的最大值)

从对手战力最弱的🐎开始,每次从 自己未出场 且 战力大于对手的这匹🐎 的🐎中挑选战力最小的一匹,如果没有🐎可以匹配,则用自己最弱的🐎去丢掉这一局


做法1:超时 每次在nums1中寻找大于nums2的最小值,若没有,则使用nums1中的最小值 O(N^2)

class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
        vector<int> ans;
        sort(nums1.begin(),nums1.end());//对nums1进行排序
        for(int i = 0;i<nums2.size();i++)
        {
            bool flag = false;
            for(int j = 0;j<nums1.size();j++)
            {
                if(nums1[j] > nums2[i])
                {
                    ans.push_back(nums1[j]);
                    nums1.erase(nums1.begin()+j);//移除nums1[j]这个元素
                    flag = true;
                    break;
                }
            }
            //当前nums1的,没有任何数比nums2[i]大,则使用nums1中最小的数字
            if(!flag)
            {
                ans.push_back(nums1[0]);
                nums1.erase(nums1.begin());
            }
        }
        return ans;
    }
};

方法2: 利用multiset 二分查找法

那么对于nums2[i],只要从数组nums1中找到第一个比nums2[i]大且没用过的元素即可,很容易想到二分法

class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
        //将nums1存入multiset(会自动进行排序)
        //遍历nums2,假设当前值为x,在multiset中二分查找>x的值的位置(upper_bound)返回的是迭代器
        //如果找到:就使用该位置的值填入对应位置(该位置有优势) ,并从multiset删除该元素
        //如果找不到,就使用multiset当前最小的值填入当前位置(放弃该位置的优势),并从multiset中删除该最小值
        multiset<int> mt(nums1.begin(),nums1.end());//自动排好序
        for(int i = 0;i<nums2.size();i++)
        {
            auto pos = mt.upper_bound(nums2[i]);//二分查找>nums2[i]的值的位置
            if(pos == mt.end())//没有找到
            {
                pos = mt.begin();//用当前最小的数匹配
            }
            nums1[i] = *pos;//复用nums1的空间,不需要额外开辟空间!
            mt.erase(pos);//把这个数删除掉
        }
        return nums1;
    }
};

[856. 括号的分数]

leetcode.cn/problems/sc…

image-20221010154148036


求各个 '()' 在它所在层的分数, 然后加起来

class Solution {
public:
    //出现 '(' 代表层数+1 , 出现 ')' 代表层数 -1
    //(()(()))
    //(()        +2^(2-1)
    //((()       +2^(3-1))
    //求的是(2的(当前括号的深度-1))的平方的值,
    int scoreOfParentheses(string S) {
        int deep=0,ans=0;
        for(int i=0;i<S.length();i++){
            if(S[i] == '(')
                deep++;
            else
                deep--;
            if(S[i]==')' && S[i-1]=='(')
                ans += 1 << deep;
        }
        return ans;
    }
};