leetcode每日一题day15(24.9.25)——公司命名


思路:首先如果没有相同的后缀,则无论只要不是相同的首字母交换都不会出现重复情况,如果有重复后缀,则还需多增加个不能和,首字符与另一相同后缀字串的首字符相同的字串交换。

主要矛盾已经明确,则可对矛盾进行分析。 首先把范围缩小到只有两种不同首字母,对于这种情况

如果首字符相同 肯定是0

如果没有相同后缀的情况 , 为字母A开头字串集合.size() x 字母B开头字串集合.size()

如果有相同后缀的情况下 为**(A开头字串集合.size()-有相同后缀的字串数) x(B开头字串集合.size()-有相同后缀的字串数)**

因为一旦对有相同的后缀字符进行替换后,必定会重复,所有等同于没有这个字母


基于上述:扩展到26种首字符也相同,只是需要遍历所有组合即可

方案一:按首字母进行分组

分组完成即可遍历所有组合进行计算

cpp 复制代码
class Solution {
public:
    long long distinctNames(vector<string>& ideas) {
        unordered_set<string> rec[26];
        for (auto& s : ideas) {
            rec[s[0] - 'a'].insert(s.substr(1));
        }
        //分组完成
        long long ans = 0;
        for (int a = 1; a < 26; a++) {
            for (int b = 0; b < a; b++) {//遍历所有组合
                int m = 0;
                for (auto& s : rec[a]) {//如果有重复的累计一下
                    m += rec[b].count(s);
                }
                ans += (long long) (rec[a].size() - m) * (rec[b].size() - m);
            }
        }
        return ans * 2; //反转也算一次
    }
};

方案二:按后缀进行分组

按后缀也是同样的道理,但可使用位运算存储一个后缀,所有的全部首字母,并且优化结构,把时间均摊到,初始化阶段,时间复杂度有所降低。

cpp 复制代码
long long distinctNames(vector<string>& ideas) {
        int size[26]{}; 
        int intersection[26][26]{}; 
        unordered_map<string, int> groups; 
        for (auto& s : ideas) {
            int b = s[0] - 'a';
            size[b]++; 
            auto suffix = s.substr(1);
            int mask = groups[suffix];
            groups[suffix] = mask | 1 << b; 
            for (int a = 0; a < 26; a++) { 
                if (mask >> a & 1) { 
                    intersection[b][a]++;
                    intersection[a][b]++;
                }
            }
        }

        long long ans = 0;
        for (int a = 1; a < 26; a++) { 
            for (int b = 0; b < a; b++) {
                int m = intersection[a][b];
                ans += (long long) (size[a] - m) * (size[b] - m);
            }
        }
        return ans * 2; 
    }
相关推荐
程序员-King.2 分钟前
day136—快慢指针—重排链表(LeetCode-143)
算法·leetcode·链表·快慢指针
万行2 分钟前
差速两轮机器人位移与航向角增量计算
人工智能·python·算法·机器人
qq_336313932 分钟前
java基础-多线程练习
java·开发语言·算法
我是一只小青蛙8883 分钟前
C++核心过渡:类与对象精讲
开发语言·c++
不知名XL4 分钟前
day25 贪心算法 part03
算法·贪心算法
玖釉-8 分钟前
Windows 下 VS2022 编译运行 Khronos Vulkan Samples 全避坑指南
c++·windows·图形渲染
期待のcode15 分钟前
Java虚拟机的垃圾回收器
java·开发语言·jvm·算法
星火开发设计18 分钟前
C++ 分支结构:if-else 与 switch-case 的用法与区别
开发语言·c++·学习·算法·switch·知识·分支
txzrxz20 分钟前
数据结构有关的题目(栈,队列,set和map)
数据结构·c++·笔记·算法··队列
Two_brushes.27 分钟前
C++ 常见特殊类的设计(含有单例模式)
开发语言·c++