哈希表 - 寻找独一无二的糖葫芦串 题目解析 | 豆包MarsCode AI刷题

100 阅读4分钟

1. 问题回顾

问题描述

小C有nn串长度为mm的糖葫芦,每串糖葫芦可以用一个字符串表示。每个糖葫芦的甜度是所有字符甜度的总和,其中每个字符的甜度为该字符与 'a' 的差值。例如,字符 'a' 的甜度为 00,字符 'b' 的甜度为 11,依次类推,字符 'z' 的甜度为 2525。

你需要帮助小C找到甜度最大的独一无二的糖葫芦。糖葫芦独一无二当且仅当它与其他n−1n−1根糖葫芦都不同,且翻转后的字符串也不能与其他糖葫芦相同。例如,糖葫芦 "abc" 与 "cba" 视为相同的糖葫芦。

如果没有独一无二的糖葫芦,则返回0。


测试样例

样例1:

输入:n = 3, m = 3, strings = ["ccz", "cba", "zcc"]
输出:3

样例2:

输入:n = 2, m = 3, strings = ["abc", "cba"]
输出:0

样例3:

输入:n = 5, m = 2, strings = ["aa", "bb", "ab", "ba", "cc"]
输出:4

2. 思路分析

  1. 计算每串糖葫芦的甜度

    • 每个字符的甜度是该字符与 'a' 的差值。
    • 将每串糖葫芦中所有字符的甜度相加,得到该串糖葫芦的总甜度。
  2. 检查糖葫芦的唯一性

    • 对于每串糖葫芦,检查它是否与其他的糖葫芦相同,或者它的翻转字符串是否与其他糖葫芦相同。
    • 如果某串糖葫芦是独一无二的(即它和它的翻转字符串都不与其他糖葫芦相同),则记录它的甜度。
  3. 找到甜度最大的独一无二的糖葫芦

    • 在所有独一无二的糖葫芦中,找到甜度最大的那一个。
    • 如果没有独一无二的糖葫芦,则返回0。

3. 代码解释

代码解释:

#include <vector>
#include <string>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>

using namespace std;

int calculate_sweetness(const string& s) {
    int sweetness = 0;
    for (char c : s) {
        sweetness += c - 'a';
    }
    return sweetness;
}

int find_unique_max_sweetness(int n, int m, vector<string>& strings) {
    unordered_map<string, int> sweetness_dict;
    unordered_set<string> unique_strings;
    
    for (const string& s : strings) {
        int sweetness = calculate_sweetness(s);
        string reverse_s = s;
        reverse(reverse_s.begin(), reverse_s.end());
        
        if (sweetness_dict.find(s) == sweetness_dict.end() && sweetness_dict.find(reverse_s) == sweetness_dict.end()) {
            sweetness_dict[s] = sweetness;
            unique_strings.insert(s);
        } else {
            if (sweetness_dict.find(s) != sweetness_dict.end()) {
                unique_strings.erase(s);
            }
            if (sweetness_dict.find(reverse_s) != sweetness_dict.end()) {
                unique_strings.erase(reverse_s);
            }
        }
    }
    
    if (unique_strings.empty()) {
        return 0;
    }
    
    int max_sweetness = 0;
    for (const string& s : unique_strings) {
        max_sweetness = max(max_sweetness, sweetness_dict[s]);
    }
    
    return max_sweetness;
}

int main() {
    int n = 3, m = 3;
    vector<string> strings = {"ccz", "cba", "zcc"};
    cout << find_unique_max_sweetness(n, m, strings) << endl;  // 输出:3

    n = 2, m = 3;
    strings = {"abc", "cba"};
    cout << find_unique_max_sweetness(n, m, strings) << endl;  // 输出:0

    n = 5, m = 2;
    strings = {"aa", "bb", "ab", "ba", "cc"};
    cout << find_unique_max_sweetness(n, m, strings) << endl;  // 输出:4

    return 0;
}
  1. calculate_sweetness函数:计算字符串的甜度。

  2. find_unique_max_sweetness函数

    • 使用sweetness_dict记录每串糖葫芦的甜度。
    • 使用unique_strings集合记录独一无二的糖葫芦。
    • 遍历每串糖葫芦,检查它和它的翻转字符串是否已经存在于sweetness_dict中。
    • 如果某串糖葫芦是独一无二的,则将其加入unique_strings集合。
    • 最后,找到unique_strings集合中甜度最大的糖葫芦,如果没有独一无二的糖葫芦,则返回0。

复杂度分析:

时间复杂度分析

  1. 计算每串糖葫芦的甜度

    • 对于每串糖葫芦,计算甜度的时间复杂度是O(m)O(m),其中mm是糖葫芦的长度。
    • 由于有nn串糖葫芦,总的时间复杂度是O(mn)O(m * n)
  2. 检查糖葫芦的唯一性

    • 对于每串糖葫芦,检查它和它的翻转字符串是否已经存在于 sweetness_dict 中。
    • 查找和插入操作在哈希表中的平均时间复杂度是O(1)O(1)
    • 因此,检查每串糖葫芦的唯一性的时间复杂度是O(1)O(1)
    • 由于有 nn 串糖葫芦,总的时间复杂度是O(n)O(n)
  3. 找到甜度最大的独一无二的糖葫芦

    • 遍历 unique_strings 集合,找到甜度最大的糖葫芦。
    • 遍历集合的时间复杂度是O(n)O(n)

综合以上步骤,总的时间复杂度是O(mn)O(m * n),其中mm是糖葫芦的长度,nn是糖葫芦的数量。

空间复杂度分析

  1. 存储甜度

    • 使用 sweetness_dict 存储每串糖葫芦的甜度,空间复杂度是O(n)O(n)
  2. 存储独一无二的糖葫芦

    • 使用 unique_strings 集合存储独一无二的糖葫芦,空间复杂度是O(n)O(n)
  3. 临时变量

    • 在计算甜度和检查唯一性时,使用了一些临时变量,但这些变量的空间复杂度是O(1)O(1)

综合以上步骤,总的空间复杂度是O(n)O(n)