1. 程式人生 > 其它 >318最大單詞長度乘積(位運算)

318最大單詞長度乘積(位運算)

技術標籤:LeetCodeleetcode演算法

1、題目描述

給定一個字串陣列words,找到length(word[i]) * length(word[j])的最大值,並且這兩個單詞不含有公共字母。你可以認為每個單詞只包含小寫字母。如果不存在這樣的兩個單詞,返回 0。

2、示例

輸入: ["abcw","baz","foo","bar","xtfn","abcdef"]
輸出: 16
解釋: 這兩個單詞為 "abcw", "xtfn"。

輸入: ["a","ab","abc","d","cd","bcd","abcd"]
輸出: 4
解釋: 這兩個單詞為 "ab", "cd"。

3、題解

基本思想:位運算,用一個32位int表示一個word中出現的字母,用int32位替代上面的vector<int>(26,0),這樣空間複雜度從O(n*26)減小到O(n),並且判斷兩個字串是否有共同字母可以通過(counts[i]&counts[j])==0。

#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<iterator>
using namespace std;
class Solution {
public:
    int maxProduct(vector<string>& words) {
        //基本思想:建立起counts二維陣列對words每個字串中的字元計數,然後通過雙重迴圈遍歷words判斷每個字串與後面字串是否存在共同字母
        int res=0;
        if(words.size()==0) return res;
        vector<vector<int>> counts(words.size(),vector<int>(26,0));
        for(int i=0;i<words.size();i++)
        {
            for(int j=0;j<words[i].size();j++)
                counts[i][words[i][j]-'a']++;
        }
        for(int i=0;i<words.size()-1;i++)
        {
            for(int j=i+1;j<words.size();j++)
            {
                bool insectflag=false;
                for(int k=0;k<words[i].size();k++)
                {
                    if(counts[j][words[i][k]-'a']>0)
                    {
                        insectflag=true;
                        break;
                    }
                }
                if(insectflag==false)
                    res=max(res,static_cast<int>(words[i].size()*words[j].size()));
            }
        }
        return res;
    }
};
class Solution1 {
public:
    int maxProduct(vector<string>& words) {
        //優化:用一個32位int表示一個word中出現的字母,用int32位替代上面的vector<int>(26,0),這樣空間複雜度從O(n*26)減小到O(n),
        //並且判斷兩個字串是否有共同字母可以通過(counts[i]&counts[j])==0
        int res=0;
        if(words.size()==0) return res;
        vector<int> counts(words.size(),0);
        for(int i=0;i<words.size();i++)
        {
            for(int j=0;j<words[i].size();j++)
                counts[i]|=1<<words[i][j]-'a';
        }
        for(int i=0;i<words.size()-1;i++)
        {
            for(int j=i+1;j<words.size();j++)
            {
                if((counts[i]&counts[j])==0)
                    res=max(res,static_cast<int>(words[i].size()*words[j].size()));
            }
        }
        return res;
    }
};
class Solution2 {
public:
    int maxProduct(vector<string>& words) {
        //另一種思路,用set_intersection求交集,但是超時
        int res=0;
        if(words.size()==0) return res;
        vector<set<char>> counts(words.size(),set<char>{});
        for(int i=0;i<words.size();i++)
        {
            for(int j=0;j<words[i].size();j++)
                counts[i].insert(words[i][j]);
        }
        for(int i=0;i<words.size()-1;i++)
        {
            for(int j=i+1;j<words.size();j++)
            {
                set<char> temp;
                set_intersection(counts[i].begin(),counts[i].end(),counts[j].begin(),counts[j].end(),inserter(temp,temp.begin()));
                if(temp.size()==0)
                    res=max(res,static_cast<int>(words[i].size()*words[j].size()));
            }
        }
        return res;
    }
};
int main()
{
    Solution2 solute;
    vector<string> words={"abcw","baz","foo","bar","xtfn","abcdef"};
    int pos=1;
    cout<<solute.maxProduct(words)<<endl;
    return 0;
}