11月17日 力扣每日一题:最大单词长度乘积 318

一、暴力解法,嘎嘎超时

力扣


     暴力搜索,动态更新 
 题目强调只包含两个小写字母,就是要求26个字母开成数组存储,
 每次两个匹配到的数组扫描之后,用存储的数组进行比较,如果两个计数数组都存在大于等于一的元素,这两个没戏了
 其次可以看一下这些字母,排序之后!!排序个屁,已验证,字符串数组无法排序
 */
 //万物皆自暴力而来优化。冲冲冲!
 class Solution 
 {
     public int maxProduct(String[] words) 
     {
         int lenArr = words.length;
         int lenMax = Integer.MIN_VALUE;
         int curlen = 0;
         for(int i=0;i=1 && cntj[p]>=1)
                     flag = 1;
                 }
                 if(flag == 0)
                 {
                     int leni = words[i].length();
                     int lenj = words[j].length();
                     // curlen= words[i].length() * words[j].length();
                     curlen = leni * lenj ;  
                 }

                 lenMax = lenMax > curlen ? lenMax : curlen;
             }
         }
         return lenMax;
     }
 }

在力扣答题环境中超时,IDEA中题目给的样例都能过,大致应该没啥问题

就是超时~


二、三叶姐的每日一题题解(未优化)

力扣

11月17日 力扣每日一题:最大单词长度乘积 318_第1张图片

其中核心代码的分析和测试:

今天又学会了很多

三、总结如下:

1:位掩码

题目给出的 每个字符串的组成都是小写字母,这个信息要用到

然后核心代码的思想,先求其是26个小写字母中第几个字母

然后向左移位,之后或运算存储,把操作复杂度降低为O(N^2) YYDS了

我还以为是放入长度26数组~

11月17日 力扣每日一题:最大单词长度乘积 318_第2张图片

位掩码这个知识点属实是给我这个土狗长见识了! 

二、或运算(“ | ”)的底层操作:

{
    { 
        int j = 31;
        // 31 = 1+2+4+8+16
        // 用01 二进制表示  0001 1111
        System.out.println(j | 1);//与末尾1 或
        System.out.println(j | 2);//表示为0000  0010  与倒数第二个1

        System.out.println(j | 4);
        System.out.println(j | 8);
        System.out.println(j | 16);
//        System.out.println(j | 16);
        // 1或1 还是 1 , 1或0,必定0
        //只有原来是 0 的位 你或进位为1的 ,才能输出
//        比如31或一个32 结果肯定是 63 ,给出一种相加的假象,最终底层是一二进制01码逐位或的

        System.out.println(31 | 32);
    }
}

{
    { 
        int j = 31;
        // 31 = 1+2+4+8+16
        // 用01 二进制表示  0001 1111
        System.out.println(j | 1);//与末尾1 或
        System.out.println(j | 2);//表示为0000  0010  与倒数第二个1

        System.out.println(j | 4);
        System.out.println(j | 8);
        System.out.println(j | 16);
//        System.out.println(j | 16);
        // 1或1 还是 1 , 1或0,必定0
        //只有原来是 0 的位 你或进位为1的 ,才能输出
//        比如31或一个32 结果肯定是 63 ,给出一种相加的假象,最终底层是一二进制01码逐位或的

        System.out.println(31 | 32);
    }
}

public class AAAATest
{
    public static void main(String[] args)
    {
//        String[] words = {"abcw","baz","foo","bar","xtfn","abcdef"};
        String[] words = {"a","aa","aaa","aaaa"};
        int n = words.length, idx = 0;
        int[] masks = new int[n];
        for (String w : words) {
            int t = 0;
            for (int i = 0; i < w.length(); i++) {
                int u = w.charAt(i) - 'a';
                t |= (1 << u);
                //此处 用 或 一句话
                //妙处有3
                //其一,通过不断用新元素减去‘a'得出是第几个字母,然后向左移位(乘2),然后不断地或
                //此处用或 ,妙处为其二 或运算,如a对应的是0,a,一个0,aa,两个0,aaa,三个0
                //但是每个字母a对移位的影响都一样
                //这种或运算只统计一次,
                //每次乘2,妙处,不会重复
                //26个字母,最大的2的25次方  从2 到 2的25次方
                //你可能会觉得一个 b 移位一位 然后乘2 变成2
                //如果字符串是 bbc ,那么两个b会不会2+2等于 4抵消一个c位移两位的结果
                //告诉你不会的,因为或运算对
                // 2|2|4只统计一次2
            }
            masks[idx++] = t;
        }
        int j = 31;
        // 31 = 1+2+4+8+16
        // 用01 二进制表示  0001 1111
        System.out.println(j | 1);//与末尾1 或
        System.out.println(j | 2);//表示为0000  0010  与倒数第二个1

        System.out.println(j | 4);
        System.out.println(j | 8);
        System.out.println(j | 16);
//        System.out.println(j | 16);
        // 1或1 还是 1 , 1或0,必定0
        //只有原来是 0 的位 你或进位为1的 ,才能输出
//        比如31或一个32 结果肯定是 63 ,给出一种相加的假象,最终底层是一二进制01码逐位或的

        System.out.println(31 | 32);
    }
}









 

你可能感兴趣的:(力扣刷题(初识),leetcode,算法,经验分享)