力扣第291场周赛

第一题:移除指定数字得到的最大结果

思路:我是想着找打最大的应该分为两中情况:1、找到一个在字符串中digit的位置后面的字典序比这个大,删掉这个。2、最后一个digit删除。但是因为有一些混乱导致22分钟才写出了,我太菜了。

代码:

class Solution {
public:
    string removeDigit(string number, char digit) {
        string s;
        int sum = 0;
        
        for(auto i : number)    if(i == digit)  sum ++;
        
        int res = 0;
        int flag = 0;
        for(int i = 0; i < number.size(); i ++){
            if(number[i] != digit)  s += number[i];
            else{
                res ++;
                if(flag)    s += number[i];
                else{
                    if(res == sum)  continue;
                    if(i < number.size() - 1 && number[i + 1] > number[i])  flag = 1;
                    else    s += number[i];
                }
            }
        }
        
        return s;
    }
};

大佬的思路:直接模拟,每次移除一digit后的最大字典序。学到了字符串还可以这样比大小(没见过世面的样子)

大佬的代码:

class Solution {
public:
    string removeDigit(string number, char digit) {
        string ans;
        int n = number.size();
        for(int i = 0; i < number.size(); i ++){
            if(number[i] == digit){
                string str = number.substr(0, i) + number.substr(i + 1, n);
                if(ans.empty() || ans < str)    ans = str;
            }
        }
        return ans;
    }
};

第二题:必须拿起的最小的连续卡牌数

思路:题目的意思相当于找到两个连续的数之间的距离的最大值,我没看清楚数据,直接暴力超时了,后来我发现可以用一个哈希表来存储一个数的值和它的下标来找打两个连续的最小值,每次要将一个数的下标更新

代码:

class Solution {
public:
    int minimumCardPickup(vector<int>& cards) {
        unordered_map<int, int> mp;
        int m = -1;
        for(int i = 0; i < cards.size(); i ++){
            if(!mp.count(cards[i])) mp[cards[i]] = i;
            else{
                int a = i - mp[cards[i]] + 1;
                if(m == -1 || m > a)    m = a;
                mp[cards[i]] = i;
            }
        }
        return m;
    }
};

 第三题:含最多k个可整除元素的子数组

思路:因为数据不大直接模拟,将子数组用字符串来存储,可以用set来统计,但是需要注意每个子数组的元素之间可以用一个符号隔开,不然会报错(这都是惨痛的教训),例如1,9 和19是两个子数组但是元素之间没有符号隔开就会被认为一个数组。 

代码:

class Solution {
public:
    int countDistinct(vector<int>& nums, int k, int p) {
        unordered_set<string> s;
        for(int i = 0; i < nums.size(); i ++){
            string str;
            int a = 0;
            for(int j = i; j < nums.size(); j ++){
                if(nums[j] % p == 0)    a ++;
                if(a > k)  continue;
                str += to_string(nums[j]);
                str += "_";
                s.insert(str);
            }
        }
        return s.size();
    }
};

第4题:字符串的总引力

思路:刚看到这道题我就感觉在哪里见过,但是我忘记了,后来被告知是蓝桥杯原题。当时训练的想了想太难了就放弃了,后来也没有搞懂(补题的重要性)。看了一下大佬的题解我感觉太妙了,

从左向右遍历,将s[i]加到s[i - 1]后面,如果s[i]在前面都没有出现,那么每个子串的引力值都会加1,最后还会加上一个1(字符串s[i]);如果s[i]在之间出现并且上次出现的下标为j,那么子串s[0, i - 1], s[1, i - 1], ... , s[j, i - 1]后面加上s[i]的引力值都不会变化,但是后面的都会加1,最后在加上1(字符串s[i]).

代码:

class Solution {
public:
    long long appealSum(string s) {
        long long sum = 0, res = 0;
        vector<int> st(26, -1);
        for(int i = 0; i < s.size(); i ++){
            int c = s[i] - 'a';

            res += i - st[c];
            sum += res;
            st[c] = i;
        }
        return sum;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值