LeetCode 1239. Maximum Length of a Concatenated String with Unique Characters

思路

这道题维护一个集合 Set,从索引0开始遍历,每次遍历判断集合里的每个 String 和当前的字符串 arr[i] 能否组成新的无重复字符的字符串,若能,添加到一个临时集合中。每一次遍历后,要将这个临时集合添加到总集合 Set 中,并把当前字符串 arr[i] 也添加到 Set 中,以便下一次的遍历。

一些细节

位图

为了简单表示两个字符串是否有重复,考虑到只有小写字母,我们用一个 int 变量来替换每一个字符串。‘a’ 映射到倒数第一位,‘b’映射到倒数第二位…依此推论

所以,字符串映射到整数的函数如下:

public int getMap(String s){
        int ans = 0;
        for(int i=0;i<s.length();i++){
            int tmp = 1 << (s.charAt(i)-'a');
            if((ans & tmp)!=0){
                return 0;
            }
            ans |= tmp;
        }
        return ans;
}

要注意的是,如果 ans & tmp 不为 0,说明这个字符串中有重复的字母,直接返回 0,代表不要用这个字符串。

统计字符串中字符的个数

由于我们把字符串映射到了一个整数上,就要有一个判断总的字符个数的函数。

public int cal(int i){
        int ans = 0;
        while(i>0){
            i = i&(i-1);
            ans++;
        }
        return ans;
}

主要解释一下 i & (i-1) 的意思。这个操作把 i 最后的二进制位为 1 的地方变成了 0 。

主程序

做好了以上准备后,我们就直接遍历就行了。。。注意如果 map[i]为0,说明此时的字符串有重复数,不满足要求,直接跳过就好。

class Solution {
    public int maxLength(List<String> arr) {
        int res = 0;
        int[] map = new int[arr.size()];
        for(int i=0;i<arr.size();i++){
            map[i]=getMap(arr.get(i));
        }

        Set<Integer> set = new HashSet<>();
        
        for(int i=0;i<map.length;i++){
            if(map[i]==0){
                continue;
            }
            Set<Integer> settmp = new HashSet<>();
            for(int j: set){
                if((map[i]&j)==0){
                    settmp.add(map[i]|j);
                }
            }
            set.add(map[i]);
            set.addAll(settmp);
        }

        for(int i: set){
            res = Math.max(res, cal(i));
        }
        return res;
    }

    public int getMap(String s){
        int ans = 0;
        for(int i=0;i<s.length();i++){
            int tmp = 1 << (s.charAt(i)-'a');
            if((ans & tmp)!=0){
                return 0;
            }
            ans |= tmp;
        }
        return ans;
    }

    public int cal(int i){
        int ans = 0;
        while(i>0){
            i = i&(i-1);
            ans++;
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值