leetcode:1002. 查找常用字符

题目来源

题目描述

在这里插入图片描述

题目解析

本题可以理解为求每个字符串之间字符数量的交集,以示例1为例:

输入:[“bella”,“label”,“roller”]
输出:[“e”,“l”,“l”]
我们知道第一个字符串的字符数量列表为:

b 1
e 1
l 2
a 1

第二个字符串的字符数量列表为:

l 2
a 1
b 1
e 1

第三个字符串的字符数量列表为:

r 2
o 1
l 2
e 1

这三个求交集后的结果为:

e 1
l 2

理解题目是关键

计数

根据题目的要求,如果字符c在所有字符串中均出现了k次以及以上,那么最终da’an1中需要包含kc。因此,我们可以使用minfreq[c]存储字符c在所有字符串中出现次数的最小值。

我们可以依次遍历每一个字符串。当我们遍历到字符串s时,我们使用freq[c]统计s中每一个字符c出现的次数。在统计完成之后,我们再将每一个minfreq[c]更新为其本身与freq[c]的较小值。这样一来,当我们遍历完所有字符串之后,minfreq[c]就存储了字符c在所有字符串中出现的最小值。

由于题目保证了所有的字符均为小写字母,因此我们可以用长度为 2626 的数组分别表示 minfreq 以及 freq

在构造最终的答案时,我们遍历所有的小写字母 cc,并将minfreq[c] c 添加进答案数组即可。

class Solution {
public:
    vector<string> commonChars(vector<string>& words) {
        std::vector<int> minfreq(26, INT_MAX);
        std::vector<int> freq(26);
        for(const std::string & word : words){
            std::fill(freq.begin(), freq.end(), 0);
            for(char ch : word){
                ++freq[ch - 'a'];
            }
            for (int i = 0; i < 26; ++i) {
                minfreq[i] = std::min(minfreq[i], freq[i]);
            }
        }
        
        std::vector<std::string> ans;
        for (int i = 0; i < 26; ++i) {
            for (int j = 0; j < minfreq[i]; ++j) {
                std::string s(1, i + 'a'); // char -> string
                ans.emplace_back(s);
            }
        }
        
        return ans;
    }
};

在这里插入图片描述

class Solution {
    public List<String> commonChars(String[] A) {
        List<String> ans  = new ArrayList<>();

        int [] arr = new int[26];
        char[] v = A[0].toCharArray();
        for (char c : v){
            arr[c - 'a'] ++;
        }

        for (int i = 1; i < A.length; i++){
           int [] brr = new int[26];
            for (char c : A[i].toCharArray()){
                brr[c - 'a'] ++;
            }


            for (int j = 0; j < arr.length; j++){
                if (brr[j] < arr[j]){
                    arr[j] = brr[j];
                }
            }
        }


        for (int j = 0; j < arr.length; j++){
            while (arr[j] != 0){
                ans.add(String.valueOf((char)('a' + j)));
                arr[j]--;
            }
        }

        return ans;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值