需要一些帮助来理解leetcode 371的python解决方案。“两个整数之和”。我发现https://discuss.leetcode.com/topic/49900/python-solution/2是投票最多的python解决方案,但我有理解它的问题。
class Solution(object):
def getSum(self, a, b):
"""
:type a: int
:type b: int
:rtype: int
"""
MAX_INT = 0x7FFFFFFF
MIN_INT = 0x80000000
MASK = 0x100000000
while b:
a, b = (a ^ b) % MASK, ((a & b) << 1) % MASK
return a if a <= MAX_INT else ~((a % MIN_INT) ^ MAX_INT)
答案 0 :(得分:3)
让我们暂时忽略Null
,MASK
和MAX_INT
。
为什么这个黑魔法按位的东西有效?
计算有效的原因是因为MIN_INT
正在“汇总”(a ^ b)
和a
的位。回想一下,当位不同时,按位xor为b
,而当位相同时,则为1
。例如(其中D是十进制,B是二进制),20D == 10100B,9D = 1001B:
0
和11101B == 29D。
但是,如果你有一个携带的情况,它不能很好地工作。例如,考虑添加(按位xor)20D和20D。
10100
1001
-----
11101
糟糕。 20 + 20当然不等于0.输入10100
10100
-----
00000
项。该术语代表每个职位的“随身携带”。在while循环的下一次迭代中,我们从前一个循环中添加进位。所以,如果我们按照之前的例子,我们得到:
(a & b) << 1
现在# First iteration (a is 20, b is 20)
10100 ^ 10100 == 00000 # makes a 0
(10100 & 10100) << 1 == 101000 # makes b 40
# Second iteration:
000000 ^ 101000 == 101000 # Makes a 40
(000000 & 101000) << 1 == 0000000 # Makes b 0
为0,我们完成了,所以返回b
。该算法通常起作用,不仅适用于我概述的特定情况。正确性的证明留给读者作为练习;)
面具有什么作用?
所有掩码都在确保该值是一个整数,因为您的代码甚至都有注释表明a
,a
,并且返回类型的类型为b
。因此,由于最大可能int
(32位)是2147483647.因此,如果您将2添加到此值,就像您在示例中所做的那样,int
溢出并且您得到负值。你必须在Python中强制执行此操作,因为它不遵循Java和C ++等其他强类型语言定义的int
边界。请考虑以下事项:
int
这是没有面具的def get_sum(a, b):
while b:
a, b = (a ^ b), (a & b) << 1
return a
版本。
getSum
输出
print get_sum(2147483647, 2)
,而
2147483649
输出
print Solution().getSum(2147483647, 2)
由于溢出。
如果您将-2147483647
类型定义为仅代表32位,则故事的寓意是实现是正确的。
答案 1 :(得分:0)
这里的解决方案适用于所有情况
const childrenWithProps = React.Children.map(children, child => {
if (React.isValidElement(child)) {
return React.cloneElement(child, {newProp: 'myNewProp'})
}
return child;
});
解决方案
python默认的int size不是32bit,是非常大的数,所以为了防止溢出并避免陷入无限循环,我们使用32bit掩码将int size限制为32bit(0xffffffff)
cases
- -
- +
+ -
+ +