LeetCode 1002. 查找共用字符

leetcode.cn/problems/fi...

github.com/youngyangya... 给你一个字符串数组 words ,请你找出所有在 words 的每个字符串中都出现的共用字符(包括重复字符 ),并以数组形式返回。你可以按 任意顺序 返回答案。

示例 1:

css 复制代码
输入: words = ["bella","label","roller"]
输出: ["e","l","l"]

示例 2:

css 复制代码
输入: words = ["cool","lock","cook"]
输出: ["c","o"]

提示:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] 由小写英文字母组成

这道题意一起就有点绕,不是那么容易懂,其实就是26个小写字符中有字符 在所有字符串里都出现的话,就输出,重复的也算。

例如:

输入:"ll","ll","ll" 输出:"l","l"

这道题目一眼看上去,就是用哈希法, "小写字符","出现频率", 这些关键字都是为哈希法量身定做的啊

首先可以想到的是暴力解法,一个字符串一个字符串去搜,时间复杂度是 O(nm)O(n^m) O(nm),n是字符串长度,m是有几个字符串。

可以看出这是指数级别的时间复杂度,非常高,而且代码实现也不容易,因为要统计 重复的字符,还要适当的替换或者去重。

那我们还是哈希法吧。如果对哈希法不了解,可以看这篇:关于哈希表,你该了解这些!

如果对用数组来做哈希法不了解的话,可以看这篇:把数组当做哈希表来用,很巧妙!

了解了哈希法,理解了数组在哈希法中的应用之后,可以来看解题思路了。

整体思路就是统计出搜索字符串里26个字符的出现的频率,然后取每个字符频率最小值,最后转成输出格式就可以了。

先统计第一个字符串所有字符出现的次数,代码如下:

c++ 复制代码
int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
    hash[A[0][i] - 'a']++;
}

接下来,把其他字符串里字符的出现次数也统计出来一次放在hashOtherStr中。

然后hash 和 hashOtherStr 取最小值,这是本题关键所在,此时取最小值,就是 一个字符在所有字符串里出现的最小次数了。

代码如下:

c++ 复制代码
int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
for (int i = 1; i < A.size(); i++) {
    memset(hashOtherStr, 0, 26 * sizeof(int));
    for (int j = 0; j < A[i].size(); j++) {
        hashOtherStr[A[i][j] - 'a']++;
    }
    // 这是关键所在
    for (int k = 0; k < 26; k++) { // 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
        hash[k] = min(hash[k], hashOtherStr[k]);
    }
}

此时hash里统计着字符在所有字符串里出现的最小次数,那么把hash转成题目要求的输出格式就可以了。

代码如下:

c++ 复制代码
// 将hash统计的字符次数,转成输出形式
for (int i = 0; i < 26; i++) {
    while (hash[i] != 0) { // 注意这里是while,多个重复的字符
        string s(1, i + 'a'); // char -> string
        result.push_back(s);
        hash[i]--;
    }
}

完整代码如下:

kotlin 复制代码
class Solution {
    fun commonChars(words: Array<String>): List<String> {
        val result = mutableListOf<String>()
        if (words.isEmpty()) return result
        // 用来统计所有字符串里字符出现的最小频率
        val hash = Array(26) { 0 }

        // 用第一个字符串给hash初始化
        for ((index, ch) in words[0].withIndex()) {
            hash[ch - 'a'] = hash[ch - 'a'] + 1
        }

        val hashOtherString = Array(26) { 0 }
        // 统计除第一个字符串外字符的出现频率
        for (i in 1..<words.size) {
            for ((index, ch) in words[i].withIndex()) {
                hashOtherString[ch - 'a'] = hashOtherString[ch - 'a'] + 1
            }
            // 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
            for ((index, i) in hash.withIndex()) {
                hash[index] = hash[index].coerceAtMost(hashOtherString[index])
                hashOtherString[index] = 0
            }
        }
        
        // 将hash统计的字符次数,转成输出形式
        for ((index, i) in hash.withIndex()) {
            if (i > 0) {
                for (j in 0..<i) {
                    val char = 'a' + index
                    result.add(char.toString())
                }
            }
        }
        return result
    }
}
相关推荐
白白白小纯17 分钟前
算法篇—链表的中间节点
c语言·数据结构·算法·leetcode
Frostnova丶34 分钟前
(19)LeetCode 54. 螺旋矩阵
算法·leetcode·矩阵
Frostnova丶38 分钟前
(18)LeetCode 73. 矩阵置零
算法·leetcode·矩阵
冻柠檬飞冰走茶1 小时前
PTA基础编程题目集 7-11 分段计算居民水费(C语言实现)
c语言·开发语言·算法
得物技术1 小时前
推荐系统体验的数字化突破:得物自动化评测平台的技术实践|AICon 文章整理
算法·架构·llm
VALENIAN瓦伦尼安教学设备1 小时前
转子/行星/平行轴齿轮箱综合故障模拟实验台可复现常见机械问题
大数据·数据库·人工智能·嵌入式硬件·算法
rannn_1111 小时前
【力扣hot100】哈希表专题——从两数之和到最长连续序列
java·算法·leetcode·哈希
小保CPP2 小时前
OpenCV C++基于极值区域滤波算法的场景文本检测(OCR)
c++·人工智能·opencv·算法·计算机视觉·ocr
来一碗刘肉面2 小时前
字符串模式匹配(朴素模式匹配算法与KMP算法)
数据结构·算法
dyxal2 小时前
eˣ 的泰勒展开式:从“化繁为简”到“万物统一”的微积分之美
算法