vlambda博客
学习文章列表

【每日编程-450期】Leetcode.1002.查找常用字符



1002.查找常用字符




给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。


你可以按任意顺序返回答案。

样例一:

输入:["bella","label","roller"]
输出:["e","l","l"]

样例二:

输入:["cool","lock","cook"]
输出:["c","o"]
提示:
  1. 1 <= A.length <= 100

  2. 1 <= A[i].length <= 100

  3. A[i][j] 是小写字母


解决方法:

(1)算法的基本思想:

本题可以理解为求每个字符串之间字符数量的交集,以示例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

结果一目了然。

分析到这里其实也没啥好说的了,我们可以用hashmap来表示**字符-数量**之间的关系,但是考虑到效率的问题,我们可以使用数组来对代码进行优化。用数组res的下标i表示是哪个字符,用res[i]表示该字符出现的次数。

作者@梁越勇:https://leetcode-cn.com/u/enoch_liang/

(2)代码实现:

  
    
    
  
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Solution
{

public:
    vector<string> commonChars(vector<string> &A)
    {
        //用数组实现hash,下标表示字母,值表示字母出现次数,初始化为最大值
        vector<int> count(26, INT_MAX);
        for (int i = 0; i < A.size(); ++i)
        {
            int word[26] = {0};
            for (int j = 0; j < A[i].size(); ++j)
            {
                //使用ASCII码
                word[(int)(A[i][j] - 'a')]++;
            }
            for (int j = 0; j < 26; ++j)
            {
                //对每个字符串求交,出现次数少的获胜
                count[j] = min(count[j], word[j]);
            }
        }

        vector<string> res;
        for (int i = 0; i < count.size(); ++i)
        {
            if (count[i] > 0)
            {
                string str;
                str.push_back((char)('a' + i));
                for (int j = 0; j < count[i]; ++j)
                {
                    res.push_back(str);
                }
            }
        }
        return res;
    }
};

int main()
{
    Solution A;
    vector<string> s = {"bella""label""roller"};
    vector<string> res;
    res = A.commonChars(s);
    for (auto c : res)
    {
        cout << c;
    }
    return 0;
}

明日预告:Leetcode.521.最长特殊序列I
给定两个字符串,你需要从这两个字符串中找出最长的特殊序列。最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列)。


子序列可以通过删去字符串中的某些字符实现,但不能改变剩余字符的相对顺序。空序列为所有字符串的子序列,任何字符串为其自身的子序列。


输入为两个字符串,输出最长特殊序列的长度。如果不存在,则返回 -1。

样例:

输入: "aba", "cdc"
输出: 3
解析: 最长特殊序列可为 "aba" (或 "cdc")

说明:

  1. 两个字符串长度均小于100。

  2. 字符串中的字符仅含有 'a'~'z'。

class Solution {
public:
    int findLUSlength(string a, string b) {

    }
};