LeetCode 双周赛 85 && 单周赛 307 总结反思

一、双周赛 85

1、2379.得到K个黑块的最少涂色

(1)原题链接:力扣icon-default.png?t=M7J4https://leetcode.cn/problems/minimum-recolors-to-get-k-consecutive-black-blocks/

(2)解题思路:

        统计窗口长度为 k 且黑块最多的数量,然后用 k 减去这个数量就是要改变的最小涂色。

(3)代码:

class Solution {
public:
    int minimumRecolors(string blocks, int k) {
        int res = 0;

        int cnt = 0;
        for(int i = 0; i <= blocks.size() - k; i ++ ) {
            int tmp = 0;
            for(int j = i; j < k + i; j ++ ) {
                if(blocks[j] == 'B') tmp ++;
            }
            if(tmp >= cnt) {
                cnt = tmp;
            }
        }
        return k - cnt;
    }
};

2、2380.二进制字符串重新安排顺序需要的时间

(1)原题链接:力扣icon-default.png?t=M7J4https://leetcode.cn/problems/time-needed-to-rearrange-a-binary-string/

(2)解题思路:

        从 01 -> 10 可以看作是 1 的左移,但 1 的左边为 1 时不可移动。

        所以,最终的时间取决于 1 的左边最多有多少个 0 ,0 的个数就是需要的时间,但,我们还需要考虑,若这个有最多个 0 在左边的 1 的左边还存在 1 那么此时需要的时间需要加一。

(3)代码:

class Solution {
public:
    int secondsToRemoveOccurrences(string s) {
        int res = 0;
        int cnt = 0;
        for(int i = 0; i < s.size(); i ++ ) {
            if(s[i] == '0') cnt ++;
            else if(cnt > 0) res = max(res + 1, cnt);
        }

        return res;
    }
};

 

3、2381.字母移位II

(1)原题链接:力扣icon-default.png?t=M7J4https://leetcode.cn/problems/shifting-letters-ii/

(2)解题思路:

        本题考点前缀和。

        用一个数组保存,所有操作带来的变化,运用前缀和的思想。往前前移就在开始位置加1,结束位置+1(因为包含结束位置)的位置减1,往后移动则相反。最后,一次遍历执行操作,改变字符串。

(3)代码:

class Solution {
public:
    string shiftingLetters(string s, vector<vector<int>>& shifts) {
       int n = s.size(), m = shifts.size();
       int a[n + 1];
       memset(a, 0, sizeof(a));
       for(int i = 0; i < m; i ++ ) {
           int tmp = 1;
           if(shifts[i][2] == 0) tmp = -1;
           a[shifts[i][0]] += tmp;
           a[shifts[i][1] + 1] -= tmp;
       }
       
       int sum = a[0];
       for(int i = 0; i < n; i ++ ) {
           int tmp = (s[i] - 'a' + sum) % 26;
           if(tmp < 0) tmp += 26;
           s[i] = tmp + 'a';
           sum += a[i + 1];
       }

       return s;
    }
};

二、单周赛 307

1、2383.赢得比赛需要的最少训练时长

(1)原题链接:力扣icon-default.png?t=M7J4https://leetcode.cn/problems/minimum-hours-of-training-to-win-a-competition/

(2)解题思路:

        首先,由题可知,我们所需的精力是一定的是不会增长的,所以我们必须先保证初始精力值严格大于赢得比赛所需精力值,其次,我们再遍历energy数组,若当前经验小于energy [i],那么我们就加上energy [i] - 当前精力 + 1 的训练时长,最终所得即答案。

(3)代码:

class Solution {
public:
    int minNumberOfHours(int initialEnergy, int initialExperience, vector<int>& energy, vector<int>& experience) {
        int sum = 0;
        for(auto& a: energy) sum += a;
        
        int res = 0;
        if(sum >= initialEnergy) res += sum - initialEnergy + 1;
        
        for(auto& c: experience) {
            if(initialExperience <= c) {
                int tmp = c - initialExperience + 1;
                initialExperience += tmp + c;
                res += tmp;
            }
            else initialExperience += c;
        }
        
        return res;
    }
};

 

2、2384.最大回文数字

(1)原题链接:力扣icon-default.png?t=M7J4https://leetcode.cn/problems/largest-palindromic-number/

(2)解题思路:

        首先,保存每个数字出现的次数,然后判断是否存在某个大于零的数的个数大于等于2,若不存在则返回当前存在的最大的数(位数为1)。

        然后,求答案字符串的前半部分,从9遍历到0,若存在数字的个数大于等于2的就加到答案字符串中,然后再遍历找到进行完上述操作后存在的最大数字作为答案字符串最中间的那个数字,最后再加上前半部分的翻转后的字符串就得到了最终的结果。

(3)代码:

class Solution {
public:
    string largestPalindromic(string num) {
        int cnt[10] = {0};
        for(auto& c: num) cnt[c - '0'] ++;

        string res;
        for(int i = 9; i ; i -- ) {
            if(cnt[i] >= 2) {
                res = to_string(i);
                cnt[i] -= 2;
                break;
            }
        }

        if(res == "") {
            for(int i = 9; i >= 0; i -- ) {
                if(cnt[i]) return to_string(i);
            }
        }

        for(int i = 9; i >= 0; i -- ) {
            while(cnt[i] >= 2) {
                res += to_string(i);
                cnt[i] -= 2;
            }
        }

        string tmp = res;
        reverse(tmp.begin(), tmp.end());

        for(int i = 9; i >= 0; i -- ) {
            if(cnt[i]) {
                res += to_string(i);
                break;
            }
        }

        return res + tmp;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值