318. Maximum Product of Word Lengths

我用了O(n2) brute force解法,以為會超時,結(jié)果還好。擊敗了11%的人。然后看了下答案,很多人用了位運算判斷有沒有相似字母,但是時間復雜度跟我一樣呀。??赡苁莃it manipulation就是比較快吧。

    public int maxProduct(String[] words) {
        if (words == null || words.length <= 1)
            return 0;
        int max = 0;
        for (int i = 0; i < words.length - 1; i++) {
            for (int j = i + 1; j < words.length; j++) {
                if (!haveCommonLetter(words[i], words[j])) {
                    max = Math.max(words[i].length() * words[j].length(), max);
                }
            }
        }
        return max;
    }

    private boolean haveCommonLetter(String s1, String s2) {
        int[] map = new int[26];
        for (int i = 0; i < s1.length(); i++) {
            map[s1.charAt(i) - 'a']++;
        }
        for (int i = 0; i < s2.length(); i++) {
            if (map[s2.charAt(i) - 'a'] != 0) {
                return true;
            }
        }
        return false;
    }

bit manipulation的方法:

    public int maxProduct(String[] words) {
        if (words == null || words.length == 0)
            return 0;
        int len = words.length;
        int[] value = new int[len];
        for (int i = 0; i < len; i++) {
            String tmp = words[i];
            value[i] = 0;
            for (int j = 0; j < tmp.length(); j++) {
                value[i] |= 1 << (tmp.charAt(j) - 'a');
            }
        }
        int maxProduct = 0;
        for (int i = 0; i < len; i++)
            for (int j = i + 1; j < len; j++) {
                if ((value[i] & value[j]) == 0 && (words[i].length() * words[j].length() > maxProduct))
                    maxProduct = words[i].length() * words[j].length();
            }
        return maxProduct;
    }

我理解了半天,確實因為bit manipulation不常用很難一眼看出來。它用了這樣一句:

                value[i] |= 1 << (tmp.charAt(j) - 'a');

其實就是,int有32位,字母有26個,正好還多6個,可以用了mapping;于是它就把1向左移動,a移動0位,z移動25位,這樣的話比如dba就成了1011,用int表示是19。|= 這種計算很像安卓里面用來判斷兩個屬性是不是同時存在,比如xml布局里那種。最后判斷兩個數(shù)是否有重疊字母就相與一下。挺fancy的,我遇到這種題一般喜歡用array模擬map,這里提供了另一種思路。

另外,還注意到另一個人寫了一個帶有prunning字樣的代碼,就是先判斷兩個字符串長度,再判斷是不是hasCommon,可以減少幾次循環(huán),不過string.length()代碼我感覺也是要for循環(huán)的吧。。。看了String的源碼,沒找到實現(xiàn)。

public class Solution {
    public int maxProduct(String[] words) {
        int max = 0;

        Arrays.sort(words, new Comparator<String>(){
            public int compare(String a, String b){
                return b.length() - a.length();
            }
        });

        int[] masks = new int[words.length]; // alphabet masks

        for(int i = 0; i < masks.length; i++){
            for(char c: words[i].toCharArray()){
                masks[i] |= 1 << (c - 'a');
            }
        }
    
        for(int i = 0; i < masks.length; i++){
            if(words[i].length() * words[i].length() <= max) break; //prunning
            for(int j = i + 1; j < masks.length; j++){
                if((masks[i] & masks[j]) == 0){
                    max = Math.max(max, words[i].length() * words[j].length());
                    break; //prunning
                }
            }
        }

        return max;
    }
}

扯的有點遠了。

ref:
https://discuss.leetcode.com/topic/35539/java-easy-version-to-understand/2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容