力扣竞赛245期(上)

95 阅读1分钟

这是我参与更文挑战的第17天,活动详情查看:更文挑战

1897. 重新分配字符使所有字符串都相等

截屏2021-06-16 下午9.49.05.png

思路分析

第一题难度必定是穷举级别,因此直接for循环统计字母的数量除以总size,都能整除,则说明可以平均分配。

代码

十分简单,毫无意义

class Solution {
public:
    bool makeEqual(vector<string>& words) {
        int arr[26];
        for(int i = 0; i < 26; i++) arr[i] = 0;
        for(int i = 0; i < words.size(); i++){
            string s = words[i];
            for(char c :s){
                arr[c - 'a'] ++;
            }
        }
        int len = words.size();

        for(int i = 0; i < 26; i++){
            // printf(" %d ",arr[i]);
            if (arr[i] % len != 0){
                return false;
            }
        }
        return true;
    }
};

1899. 合并若干三元组以形成目标三元组

截屏2021-06-16 下午11.36.43.png

思路分析

这道题十分简单,看起来很难,但我们注意到他合并三元组的方式是取最大值,而我们知道:

如果a,b,c,d中a为最大值,那么a,b,c或者a,c等所有包含a本身的子集,最大值均为a。换句话说我们可以尽可能使用几乎所有三元组用于合并。

那么这个“尽可能”,是对哪些三元组没可能呢?从题意我们知道,我们不能使三元组合并和三元组值大于目标三元组对应的值。因此如果对应值大于目标三元组对应的值,就不合并该三元组。

根据上述思路写出代码:

class Solution {
public:
    bool mergeTriplets(vector<vector<int>>& triplets, vector<int>& target) {
        int a = 0,b = 0, c = 0;
        for(int i = 0; i < triplets.size(); i++){
            if(triplets[i][0] <= target[0] && triplets[i][1] <= target[1] && triplets[i][2] <= target[2]){
                a = max(a, triplets[i][0]);
                b = max(b, triplets[i][1]);
                c = max(c, triplets[i][2]);
            }
        }
        return a == target[0] && b == target[1] && c == target[2];
    }
};

1898. 可移除字符的最大数目

截屏2021-06-16 下午11.41.12.png

思路分析

已知:如果删除前k个下标,p是s的子集,那么删除前k-1个下标,p仍然是s的子集。这样我们就可以使用二分查找进行剪枝了。

二分查找的思路已经说过很多次了,首先确定mid是什么,究竟是最后一个合法的k,还是最后一个合法的k的后一个元素,因此就要进一步考虑left与right的范围,以及while()和if()的判断

但我没写出来通过的代码,卡在了第53个用例。因此代码下期再发