Leetcode每日一题之最大单词长度乘积 算法

题目描述:给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。

示例 1:

输入:words = [“abcw”,“baz”,“foo”,“bar”,“xtfn”,“abcdef”]
输出:16
解释:这两个单词为 “abcw”, “xtfn”。
示例 2:

输入:words = [“a”,“ab”,“abc”,“d”,“cd”,“bcd”,“abcd”]
输出:4
解释:这两个单词为 “ab”, “cd”。
示例 3:

输入:words = [“a”,“aa”,“aaa”,“aaaa”]
输出:0
解释:不存在这样的两个单词。

提示:

2 <= words.length <= 1000
1 <= words[i].length <= 1000
words[i] 仅包含小写字母

package leetcode;

public class p318 {
    public static void main(String[] args) {
        String[] words={"a","aa","aaa","aaaa"};
        System.out.println(maxProduct2(words));
    }

    /**
     * 不出意外地时间超限
     *思路:使用双重遍历遍历所有字符串,判断是否含有重复字母,若没有则与现在最大的比较大小,保存大的那个
     * 时间复杂度O(n3) 空间复杂度O(1)
     */
    public static int maxProduct(String[] words) {
        int answer=0;
        for (int i=0;i<words.length;i++){
            for (int j=i+1;j<words.length;j++) {
                Boolean contain = isContain(words[i], words[j]);
                if (!contain) {
                    int tmp=words[i].length() * words[j].length();
                    if (answer>tmp)
                        continue;
                    else
                        answer=tmp;
                }
            }
        }
       return answer;
    }
    // 判断这个两个字符串中是否含有相同的字符
    public static Boolean isContain(String a,String b){
        if (a.length()<b.length()){
            for (int i=0;i<a.length();i++){
                if (b.contains(String.valueOf(a.charAt(i)))){
                    return true;
                }
            }
        }else {
            for (int i=0;i<b.length();i++){
                if (a.contains(String.valueOf(b.charAt(i)))){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 思路:位运算的方式,将单词用一个int类型表示,低26位上有1表示出现过。在判断两个单词是否有字母重复时只要与一下就行了
     * 时间复杂度o(n2) 空间复杂度O(n)
     */
    public static int maxProduct2(String[] words) {
        int[] masks=new int[words.length]; // 表示单词数组的掩码数组
        for (int i=0;i< words.length;i++){
            int mask=0;
            for (int j=0;j<words[i].length();j++){ // 经过这个循环就能得到第i个单词的掩码
                int left=words[i].charAt(j)-'a';
                mask|=1<<left;
            }
            masks[i]=mask;
        }
        int answer=0;
        for (int i=0;i< words.length;i++){
            for (int j=i+1;j< words.length;j++){
                if ((masks[i]&masks[j])==0){ // 如果两个单词没有相同的字母,则将其与现有最大的进行比较
                    answer=Math.max(answer,words[i].length()*words[j].length());
                }
            }
        }
        return answer;
    }
}

总结:当要判断两个集合中是否含有相同的元素时,可以将集合中的元素使用掩码来表示,只要使用一次与运算就可以知道两个集合中是否含有相同的元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值