这个题目,果不其然,咱就直接暴力破解加剪枝,比对两个单词是是否有相同字母。时间复杂度就O(n*n*wordlength*wordlength)大概这么多吧,确实有点多。上代码了:
int maxProduct(vector<string>& words) { int max = 0; int flag; //从单词长度最长的开始两两比对 for(int i=words.size() - 1;i > 0; i--){ for(int j = i - 1;j >= 0; j--){ int t = words[i].length() * words[j].length(); if(t <= max){ continue; } flag = 1; for(int m = 0;m < words[i].length();m++){ for(int n = 0;n < words[j].length();n++){ if(words[i][m] == words[j][n]){ flag = 0; break; } }//当两个单词有相同的字母时,就这两个单词就可以停止比对了 if(flag == 0){ break; } } if(flag == 1){ max = t>max?t:max; } } } return max; }
然后再看看官方题解:如果可以将判断两个单词是否有公共字母的时间复杂度降低到 O(1),则可以将总时间复杂度降低到 O(n^2)。可以使用位运算预处理每个单词,通过位运算操作判断两个单词是否有公共字母。由于单词只包含小写字母,共有 26个小写字母,因此可以使用位掩码的最低 26位分别表示每个字母是否在这个单词中出现。将 a 到 z 分别记为第 0 个字母到第 25 个字母,则位掩码的从低到高的第 i位是 1 当且仅当第 i个字母在这个单词中。
用数组masks 记录每个单词的位掩码表示。计算数组 \textit{masks}masks 之后,判断第 i个单词和第 j 个单词是否有公共字母可以通过判断 masks[i] & masks[j] 是否等于 0 实现,当且仅当masks[i] & masks[j]=0 时第 i个单词和第 j 个单词没有公共字母,此时使用这两个单词的长度乘积更新单词长度的最大乘积。
class Solution { public: int maxProduct(vector<string>& words) { int length = words.size(); vector<int> masks(length); for (int i = 0; i < length; i++) { string word = words[i]; int wordLength = word.size(); for (int j = 0; j < wordLength; j++) { masks[i] |= 1 << (word[j] - 'a'); } } int maxProd = 0; for (int i = 0; i < length; i++) { for (int j = i + 1; j < length; j++) { if ((masks[i] & masks[j]) == 0) { maxProd = max(maxProd, int(words[i].size() * words[j].size())); } } } return maxProd; } }; 作者:LeetCode-Solution 链接:https://leetcode.cn/problems/aseY1I/solution/dan-ci-chang-du-de-zui-da-cheng-ji-by-le-l5mu/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。