算法小知识----11.18----最大单词长度乘积

219 阅读2分钟

这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

最大单词长度乘积

该题出自力扣的318题——最大长度乘积(中等题),题解是消化于官方题解,也算是对于基础运算符有了一知半解

审题

给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。

  • 这道题不难理解,就是给一个数组,找出数组内长度之乘积最大的数,并且携带一个条件:两个字符串不能有相同的字符

  • (×)方法一:双指针

    • 最初是真的有点冲昏头脑,妄想用双指针的方式去实现;
    • 首尾指针,并且加个判断循环:两个字符之间是否存在相同字符
    • 但是有个最大的败北就是,指针的移动,移动最小的最终结果却不一定正确
  • (√)方法二:暴力循环

    • 暴力循环也不是不行,首先要双重for循环遍历数组
    • 每两个字符串之间再比较是否有相同
    • 光是上面都几重循环了,击败5%
  • (√)方法三:位运算

    • 首先简单先了解位运算

      • & :二进制位数都为1才为1,否则都为0
      • | :二进制有一个位数为1即为1,否则为0
      • >> 右移位
      • << 左移位
    • 循环数组,对数组内的字符串再次进行字符循环

      • 字符 - ‘a’ 获取ASSIC值,并且用1右移来记录字母,再用 | 来存储字母存放的位置
      • 再次循环,用 & 运算来计算是否有相同字符,没有则比较最大值

编码

    public static int maxProduct(String[] words) {
        int n = words.length;
        int[] masks = new int[n];
        for (int i = 0; i < n; i++) {
            String word = words[i];
            int wn = word.length();
            for (int j = 0; j < wn; j++) {
                int num = word.charAt(j) - 'a';
                int a = 1 << num ;
                masks[i] = masks[i] | a;
            }
        }
        int maxProd = 0;
        for (int i = 0; i < masks.length; i++) {
            for (int j = i+1; j < masks.length; j++) {
                if ((masks[i] & masks[j]) == 0){
                    maxProd = Math.max(maxProd,words[i].length() * words[j].length());
                }
​
            }
​
        }
        return maxProd;
    }

1637137616(1).jpg