当前位置: 首页 > article >正文

【每日一题】LeetCode 2306.公司命名(位运算、数组、哈希表、字符串、枚举)

【每日一题】LeetCode 2306.公司命名(位运算、数组、哈希表、字符串、枚举)

题目描述

给定一个字符串数组 ideas,表示在公司命名过程中使用的名字列表。我们需要从 ideas 中选择两个不同的名字,称为 ideaAideaB。然后交换 ideaAideaB 的首字母。如果交换后得到的两个新名字都不在 ideas 中,那么这两个名字串联起来(中间用一个空格分隔)就是一个有效的公司名字。我们需要返回不同且有效的公司名字的总数。

在这里插入图片描述

输入示例

示例 1:

输入:ideas = ["coffee","donuts","time","toffee"]
输出:6
解释:下面列出一些有效的选择方案:
- ("coffee", "donuts"):对应的公司名字是 "doffee conuts" 。
- ("donuts", "coffee"):对应的公司名字是 "conuts doffee" 。
- ("donuts", "time"):对应的公司名字是 "tonuts dime" 。
- ("donuts", "toffee"):对应的公司名字是 "tonuts doffee" 。
- ("time", "donuts"):对应的公司名字是 "dime tonuts" 。
- ("toffee", "donuts"):对应的公司名字是 "doffee tonuts" 。
因此,总共有 6 个不同的公司名字。

下面列出一些无效的选择方案:
- ("coffee", "time"):在原数组中存在交换后形成的名字 "toffee" 。
- ("time", "toffee"):在原数组中存在交换后形成的两个名字。
- ("coffee", "toffee"):在原数组中存在交换后形成的两个名字。

示例 2:

输入:ideas = ["lack","back"]
输出:0
解释:不存在有效的选择方案。因此,返回 0 。

提示

  • 2 <= ideas.length <= 5 * 10^4
  • 1 <= ideas[i].length <= 10
  • ideas[i] 由小写英文字母组成
  • ideas 中的所有字符串互不相同

思路分析

  1. 遇到困难题,我们先可以尝试暴力枚举,然后再逐步优化!
  2. 首先,我们将 ideas 数组中的所有字符串添加到一个 HashSet 中,以便快速检查某个字符串是否在 ideas 中。
  3. 然后,我们使用两层循环遍历 ideas 数组,外层循环选择 ideaA,内层循环选择 ideaB
  4. 对于每一对 ideaAideaB,我们交换它们的首字母,得到两个新的名字 newIdea1newIdea2
  5. 我们检查这两个新名字是否都不在 ideas 中。如果不在,那么这是一个有效的公司名字,计数器 count 增加。
  6. 由于每一对 ideaAideaB 可以交换两次(ideaAideaBideaBideaA),所以我们需要将最终的计数器 count 乘以 2。

代码实现(暴力枚举)

class Solution {
    public long distinctNames(String[] ideas) {
        // 将所有名字存入HashSet中,方便快速查找
        HashSet<String> set = new HashSet<>();
        for (String idea : ideas) {
            set.add(idea);
        }
        
        // 初始化计数器
        long count = 0;
        int n = ideas.length;

        // 外层循环遍历选择ideaA
        for (int i = 0; i < n; i++) {
            char firstChar1 = ideas[i].charAt(0); // 获取ideaA的首字母
            // 内层循环遍历选择ideaB,从i+1开始避免重复
            for (int j = i + 1; j < n; j++) {
                char firstChar2 = ideas[j].charAt(0); // 获取ideaB的首字母
                
                // 交换首字母后的新名字
                String newIdea1 = firstChar2 + ideas[i].substring(1);
                String newIdea2 = firstChar1 + ideas[j].substring(1);
            
                // 如果两个新名字都不在ideas中,那么这是一个有效的公司名字
                if (!set.contains(newIdea1) && !set.contains(newIdea2)) {
                    count++;
                }
            }
        }
        // 由于每一对可以交换两次,所以最终结果需要乘以2
        return count * 2;
    }
}

思路优化

  1. 我们可以使用一个数组 groups 来存储按首字母分组的后缀。
  2. 遍历 ideas 数组,将每个字符串的后缀(去掉首字母的部分)添加到对应的 HashSet 中。
  3. 使用两层循环遍历 groups 数组,外层循环选择首字母 i,内层循环选择首字母 j(从 i+1 开始,避免重复计算)。
  4. 对于每一对首字母 ij,我们统计它们共有的后缀数量 m
  5. 计算可以形成的不同名称的数量,即 (groups[i].size() - m) * (groups[j].size() - m)
  6. 由于每一对 ideaAideaB 可以交换两次(ideaAideaBideaBideaA),所以我们需要将最终的计数器 count 乘以 2。

代码实现(思路优化)

class Solution {
    public long distinctNames(String[] ideas) {
        // 开一个set数组存储后缀
        HashSet<String>[] groups = new HashSet[26];
        for (int i = 0; i < 26; i++) {
            groups[i] = new HashSet<>(); 
        }

        // 将每个字符串的后缀按照首字母分组
        for (String str : ideas) {
            groups[str.charAt(0) - 'a'].add(str.substring(1)); // 将后缀加入到对应的 HashSet 中
        }
        long count = 0;

        // 两层循环遍历所有可能的首字母组合
        for (int i = 0; i < 26; i++) {
            for (int j = i + 1; j < 26; j++) {
                int m = 0; // 计数相同后缀的数量
                // 统计 i 组和 j 组中相同的后缀数量
                for (String s : groups[i]) {
                    if (groups[j].contains(s)) {
                        m++;
                    }
                }
                // 计算 i 组和 j 组可以形成的不同名称的数量
                count += (long)((groups[i].size() - m) * (groups[j].size() - m));
            }
        }
        return count * 2; // 每对组合可以有两种排列,因此乘以 2
    }
}

http://www.kler.cn/a/320393.html

相关文章:

  • 智慧社区平台系统提升物业管理效率与居民生活质量
  • 经验笔记:Git 基础操作指南
  • Vulnhub靶场案例渗透[9]- HackableIII
  • 5. langgraph中的react agent使用 (从零构建一个react agent)
  • 【3D Slicer】的小白入门使用指南九
  • 详细分析ip addr show 查看网络配置的命令
  • Excel 设置自动换行
  • Qt C++设计模式->组合模式
  • 25 基于51单片机的温度电流电压检测系统(压力、电压、温度、电流、LCD1602)
  • 神经网络(四):UNet图像分割网络
  • iOS 消息机制详解
  • 三光吊舱详解!
  • IT技术之电脑黑屏处理
  • 183天打造行业新标杆!BOE(京东方)国内首条第8.6代AMOLED生产线提前全面封顶
  • Java-多线程-锁
  • vue props 接收函数 function
  • 在模板字符串中不能使用element-ui组件
  • 【机器学习】ROC曲线
  • AtCoder Beginner Contest 372
  • 抓机遇,促发展——2025第十二届广州国际汽车零部件加工技术及汽车模具展览会
  • MySQL的基础用法一
  • 【论文阅读】视觉里程计攻击
  • 【机器学习】Zygote.jl
  • ollydbg 小记
  • 每天一道面试题(17):服务网格学习笔记
  • 社区团购的创新与变革——融合开源链动 2+1 模式、AI 智能名片及 S2B2C 商城小程序