取负号其实就是先取反,再加 1,需要 补码 的知识。最后再和原数相与就会保留最低位的 1。比如 1010,先取反是 0101,再加 1,就是 0110,再和 1010 相与,就是 0010 了。
diff = (diff & (diff - 1)) ^ diff; 这里 的做法
n & (n - 1) 的操作在 191 题 用过,它可以将最低位的 1 置为 0。比如 1110,先将最低位的 1 置为 0 就变成 1100,然后再和原数 1110 异或,就得到了 0010
diff = xor & ~(diff - 1) 这里 的做法
先减 1,再取反,再相与。比如 1010 减 1 就是 1001,然后取反 0110,然后和原数 1010 相与,就是 0010 了
mask=1 while((diff & mask)==0): mask <<= 1 # mask 就是我们要构造的了这里 的做法
参考资料补码为什么按位取反再加一认真看完会有收获的。