纪录一道运用位操作符的字符串比较算法

原问题
给定一个字符串数组,找到长度的最大值length(word[i]) * length(word[j]),个中两个单词中的字母无雷同。您能够假定每一个单词只包括小写字母。假如没有这两个词,返回0。

例:

Input: ["abcw","baz","foo","bar","xtfn","abcdef"]
Output: 16 
Explanation: The two words can be "abcw", "xtfn".

剖析:
这题肯定要举行交织对照(2个for轮回),但最症结的就是对照历程,也就是推断2个字符串是不是存在雷同的字符。

假如运用indexOf或许数组下标纪录都邑形成时刻复杂度大幅提拔,看了别人的答案发明运用的是位操作符<<|&,而且是在交织对照之前举行预处理,交织对照的时刻只需要简朴的推断pretreate[i] & pretreate[j]===0便可,

由于运用后效力提拔太多,剖析而且纪录一下。

先诠释val |= (1 << (word.charCodeAt(i)-aCode))

  • word.charCodeAt(i)-aCode这个很好懂,也就是a对应0,b对应1…这里的0,1数字代表的是
    二进制1背面的位数。
  • 1<<01<<1是什么呢?

    1在二进制中(32位)就是00000000000000000000000000000001<<是左移1位,

    那末1<<0照样11<<1就是(前面的零省略)101<<2就是1001<<3就是1000

    因而可知

    a就是1

    b10

    c100

    z10000000000000000000000000(25个0)。

  • |是按位或:二进制编码中,每一位二者个中一个为1,则为1,不然,则为0,

    因而 val |=就是对每一个字符兼并,比方

    ab00010|00001=>00011

    f100000

    ffff 也是 100000

    big101000010

    axdg100000000000000001001001

  • &,按位与,二进制编码中,每一位二者都为1,则为1,不然,则为0,

    例1:axdgoigd要推断是不是有反复:

    axdg是:100000000000000001001001
    
    oifd是:         100000100101000
    
    & 后:  000000000000000000001000  

    由于第4位都为1,所以末了不为0,也可得知反复的就是字母表第4位:d
     
    例2:axdglkmk要推断是不是有反复:

    效果为0,申明无反复。

    axdg是:100000000000000001001001
    
    lkmk是:           1110000000000
    
    & 后:  000000000000000000000000  

总结:这类要领运用了二进制数字的位数作为保留字符的手腕,相比起数组,散列表等,速率更快,在保留量较小(<=32)上风异常显著。

代码:

/**
 * @param {string[]} words
 * @return {number}
 */
var maxProduct = function(words) {
    let aCode='a'.charCodeAt(0)
    function compute(word){
        let val=0
        for(let i=0;i<word.length;i++){
            val |= (1 << (word.charCodeAt(i)-aCode))
        }
        return val
    }
    let pretreatment=[]
    for(let i=0;i<words.length;i++){
        pretreatment[i]=compute(words[i])
    }
    let maxSum=0
    for(let i=0;i<words.length-1;i++){
        for(let j=i+1;j<words.length;j++){
            let len1=words[i].length,len2=words[j].length
            if(len1*len2>maxSum && (pretreatment[i] & pretreatment[j])===0){
                 maxSum=len1*len2
            }
        }
    }
    return maxSum
};
    原文作者:stonehank
    原文地址: https://segmentfault.com/a/1190000016289973
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞