我试图在leetcode: https://leetcode.com/problems/maximum-product-of-word-lengths/上解决这个问题我尝试了很多方法,但都没能找到一个有效的解决方案。之后,通过讨论门户,我找到了这个解决方案。有人能告诉我这句话是怎么说的吗?value[i] |= 1 << (tmp.charAt(j) - 'a');
这是代码:
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;
}
value[i] |= 1 << (tmp.charAt(j) - 'a');
(tmp.charAt(j) - 'a')
使用字符的ASCII值并进行减法返回整数。例如,'a'-'a'
为0
,'b'-'a'
为'1','c'-'a'
为2
,…它基本上是算术。注意,结果是一个整数,你可以看到它就像索引字符(它用于位模式中的位位置)。1 << n
表示左移n
次,插入0
s。例如,如果1
是32位数字000000..00001
,并且执行1 << 3
,则会得到000000...01000
。你有了字符的索引,现在可以移动到该字符的索引,在刚才提到的例子中,你必须有一个d
,因为你移动了3
次。a |= b
相当于a = a | b
用于将字的位模式与OR运算结合。- 操作符具有决定操作顺序的优先级。在这种情况下(我假设是Java),可以找出
|=
(赋值)和<<
(移位)的操作符优先级。通过将表达式放在括号中,您可以为该表达式提供更高的优先级(正如您从数学中知道的那样)。
因此表达式的求值顺序如下:
(tmp.charAt(j) - 'a')
(计算j-th
字符的索引;让我们把索引命名为X)1 << X
(计算该字符的位置;让我们把结果命名为Y)value[i] |= Y
,相当于value[i] = value[i] | Y
(将位位置添加到位模式中)
思路如下:
- 你有一个单词列表。所以你遍历这个列表。
- 你保留一个数组
value
,它的大小等于你迭代的单词数。所以value[i]
是word[i]
的位模式 - 您遍历每个单词的字符并存储该单词的位模式(您的问题是关于获取该单词字符在该位模式中的位位置)。它是red (
|
),因此位模式表示在该单词中找到的所有字符。 - 当你有一个单词的位模式和另一个单词的位模式时,你可以and (
&
)它们:当结果为0
时,这意味着单词没有共同字符,否则它们至少有一个共同字符。