LeetCode 6094. 公司命名

6094. 公司命名

 

【集合】按照首字母来统计后半部分字符串的集合,如果两个集合之间的元素可以互换首字母,那么需要满足A集合中的没有在B中出现过,那么A集合中的元素才能换成B集合开头的字母,所以两个集合分别求补集,然后个数相乘即可,举个🌰:

假设统计完之后:

a: bb cc dd  

b: cc ee ff

显然我们发现cc在B集合中出现过了,也就是说原本以a开头的cc不能换成以b开头的cc了,所以a中可以替换成b开头的元素只有bb、dd,同理,B集合中可以替换成a开头的字符只有cc和ff,这样形成的组合共计2*2个

class Solution {
    
    // set 2:32 30
    
    public long distinctNames(String[] ideas) {
        long ans = 0;
        Map<Integer, Set<String>> map = new HashMap();
        for(var str: ideas){
            var st = str.substring(1, str.length());
            int c = str.charAt(0) - 'a';
            if(map.containsKey(c)) map.get(c).add(st);
            else {
                Set<String> set = new HashSet();
                set.add(st);
                map.put(c, set);
            }
        }
        for(var i = 0; i < 26; i++){
            if(map.containsKey(i)){
                Set<String> a = new HashSet(map.get(i));
                for(var j = i + 1; j < 26; j++){
                    if(map.containsKey(j)){
                        Set<String> b = new HashSet(map.get(j));
                        Set<String> d = new HashSet(a);
                        d.removeAll(b);
                        b.removeAll(a);
                        ans += (long)d.size() * b.size() * 2;
                    }
                }
            }
        }
        return ans;
    }
}

【预处理】直接通过哈希表来计算a开头的字符串替换成另外a-z开头的字符串共有多少个不在原来的字符串集合中。即建立一个26*26的二维数组记录以i开头的所有字符串替换成以j开头后不重复的有多少个。

class Solution {

    // 3:35 15

    public long distinctNames(String[] ideas) {
        Set<String> set = new HashSet(){{
            for(var x: ideas) add(x);
        }};
        int[][] arr = new int[26][26];
        for(var x: ideas){
            int i = x.charAt(0) - 'a';
            var str = x.substring(1, x.length());
            for(var j = 0; j < 26; j++){
                var c = (char)(j + 'a'); 
                if(!set.contains(c + str)){
                    arr[i][j]++;
                }
            } 
        }
        long ans = 0;
        for(var i = 0; i < 26; i++){
            for(var j = 0; j < 26; j++){
                ans += arr[i][j] * arr[j][i];
            }
        }
        return ans;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值