LeetCode第259场周赛题解

2021.9.19第259场周赛

2011.执行操作后的变量值

思路

从前往后模拟,检查每个字符串中是否含有“+”,若是则加1,否则减1

代码

class Solution {
public:
    int finalValueAfterOperations(vector<string>& op) {
        int ans = 0;
        for (auto i : op) {
            if (i.find('+') != -1)
                ans ++ ;
            else
                ans -- ;
        }
        return ans;
    }
};

2012. 数组美丽值求和

思路

类似单调栈思想,找到左边和右边第一个比本身大和小的数,若不存在,则本身满足左边均小于和右边均大于,满足美丽值2的条件
美丽值1的条件扫描一遍即可判断

代码

class Solution {
public:
    int sumOfBeauties(vector<int>& nums) {
        int n = nums.size();
        vector<int> l(n);
        vector<int> r(n);
        
        int maxn = nums[0];
        for (int i = 1; i < n; i ++ ) {
            if (nums[i] > maxn)
                l[i] = 1;
            maxn = max(maxn, nums[i]);
        }

        int minn = nums[n - 1];
        for (int i = n - 2; i >= 0; i -- ) {
            if (nums[i] < minn)
                r[i] = 1;
            minn = min(minn, nums[i]);
        }
        int ans = 0;
        for (int i = 1; i < n - 1; i ++ ) {
            if (l[i] && r[i])
                ans += 2;
            else if (nums[i] > nums[i - 1] && nums[i] < nums[i + 1])
                ans ++ ;
        }
        return ans;
    }
};

2013. 检测正方形

思路

将所有点用map记录下来,每次检查和当前点在同一行的点能否和其他点组成正方形

代码

class DetectSquares {
public:
    map<pair<int, int>, int> mp; //记录每个点的数量
    map<int, set<pair<int, int>>> g; //记录每一行的点 去重用set
    
    DetectSquares() {
        
    }
    
    void add(vector<int> p) {
        mp[{p[0], p[1]}] ++ ;
        g[p[1]].insert({p[0], p[1]});
    }
    
    int cnt = 0;
    int count(vector<int> p) {
        cnt ++ ;
        int x = p[0], y = p[1];
        int ans = 0;

        for (auto k : g[y]) { //每次判断同一行是否有满足条件的点
            int i = k.first;
            if (i != x && mp[{i, y}] > 0) {
                int r = abs(x - i);
                
                if (mp[{i, y + r}] > 0 && mp[{x, y + r}] > 0) //往上
                    ans += mp[{i, y}] * mp[{i, y + r}] * mp[{x, y + r}];
                if (mp[{i, y - r}] > 0 && mp[{x, y - r}] > 0) //往下
                    ans += mp[{i, y}] * mp[{i, y - r}] * mp[{x, y - r}];
            }
        }
        return ans;
    }
};

/**
 * Your DetectSquares object will be instantiated and called as such:
 * DetectSquares* obj = new DetectSquares();
 * obj->add(point);
 * int param_2 = obj->count(point);
 */

2014. 重复 K 次的最长子序列

思路

统计出 s s s 中出现次数大于等于 k k k 的字符,答案只能由这些字符组成,而这些字符的个数不会超过 ⌊ n k ⌋ \lfloor\frac{n}{k}\rfloor kn ,而 n < 8 ∗ k n < 8 * k n<8k,故字符数量最多为 7 7 7
暴力枚举目标字符的所有可能组成的字符串,再检查是否满足要求,长度最长且字典序最大的字符串即为所求

代码

class Solution {
public:
    bool check(string s, string t, int k) { //检查k个t是否是s的子串
        string sc = "";
        while (k -- )
            sc += t;
        int j = 0;
        for (int i = 0; i < s.size(); i ++ ) {
            if (j < sc.size() && s[i] == sc[j])
                j ++ ;
        }
        return j == sc.size();
    }

    string longestSubsequenceRepeatedK(string s, int k) {
        vector<int> cnt(26); //记录各个字符出现的次数

        for (auto c : s)
            cnt[c - 'a'] ++ ;

        vector<char> fc; //记录出现大于等于k次的字符
        for (int i = 0; i < 26; i ++ )
            if (cnt[i] >= k)
                fc.push_back('a' + i);
        
        vector<string> fs[8]; //从小到大枚举所有由出现大于k次的字符组成的字符串 fs[i]表示长度为i
        fs[0].push_back("");
        int len;
        for (len = 1; len < 8; len ++ ) { //枚举长度 每个更长的字符串都是由长度减1的满足要求的字符串转化而来
            for (string la : fs[len - 1]) {
                for (char c : fc) {
                    if (check(s, la + c, k))
                        fs[len].push_back(la + c);
                }
            }
            if (fs[len].size() == 0)
                break;
        }
        sort(fs[len - 1].begin(), fs[len - 1].end()); //排序取字典序最大
        return fs[len - 1].back();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值