「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战」。
题目
给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。
思路分析
先尝试一个最笨的思路,两层for循环遍历i,j,比较word[i],words[j]看看是否有公共字母,如果没有公共字母,则两者长度相乘,并更新最大单词长度乘积。
而比较words[i],words[j]的时间复杂度本身为n**2,因此会造成总复杂度过大。
所以应该想办法使words[i],words[j]比较公共字母这步时间复杂度变小,我们能否通过子问题的方式解决这个时间复杂度呢?不能,因此选择位运算。
位运算用来比较两个字符串是否有相同字符,位运算总共有且,或,异或三种常见写法,这里很明显使用且更合适些。
//将单词按照26字母分为26位
//使用如下方法可以不在意字母的顺序(不用从是否有a,是否有b的顺序判断)
int wordLength = word.size();
for (int j = 0; j < wordLength; j++) {
masks[i] |= 1 << (word[j] - 'a');
}
简单说说
这篇文章拖了好久,一个是看了五分钟真不会(因为往动态规划想了好久),一个是断了签积极性确实也没有了。不过事后看题解·发现这题确实也不难,先穷举再剪枝的思路还是没有变,只是剪枝逻辑变成了位运算。
说到位运算可能有些人不熟悉,其实也就是个吃过见过的事
可以看看我之前写的这篇文章:没时间看CSAPP?那总要看看实验吧——DATALAB