出师不利的leetCode之旅,意料之中的艰难升级路
作为一名有追求的coder,无论是为了巩固基础还是训练思维亦或是面试找工作的需要,刷题都是一个很好的手段。怀揣着这样一个目的,我打开了大名鼎鼎的LeetCode网站,这个据说国外跳槽准备中的必备单品,虽然我在国内,虽然我目前不可能找到什么高端工作…
但本着定个100分的目标,最后60分也够了的原则。我义无反顾的打开了它,选中了语言Java,鸡贼的按难度准确的说是通过率排序,当然是简单的排在前面,我这点自知之明还是有的。就这样得到了我第一个要挑战的题目,就是本文的主题。结果还是让我惊讶,因为我思考了一段时间后发现不会做…
简单的介绍了背景加自黑之后,结果就是我找到了答案,当然答案有一点问题,因为不是java的,稍作改动就可以了。对于我来说如果能做出来当然是最好的,做不出来也不要紧,通过学习别人的答案,掌握薄弱的知识点,之后在多刷几遍之后不说能倒背如流,至少下次碰到类似的能知道大概思路就是胜利了。

1.二进制表示(这个谁都会)2.按位与运算符(&)参加运算的两个数据,按二进制位进行“与”运算。运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;即:两位同时为“1”,结果才为“1”,否则为0例如:3&5 即 0000 0011 & 0000 0101 = 0000 0001 因此,3&5的值得1。3.异或运算符(^)参加运算的两个数据,按二进制位进行“异或”运算。运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
有了这些基础之后,我们注意到异或运算,很明显如果把x和y进行异或运算的话,最终结果中1的个数就该是此次返回的结果,那么我们有什么办法来做到呢?答案是有的(当然你可以循环每一位和1进行比较),这里我就直接说了,因为这个你或许自己想不出来,但基本你知道了以后后面就可以直接用了。
那就是不断对result & (result -1)循环,直到结果为0,循环的次数就是1的个数。这里我说一下我的理解,比如现在result为1010,那么1的个数显然是2个,1010&1001 = 1000, 1000 & 0111 = 0,循环结束,循环次数就是1的个数。为何会有这个结果呢?通过观察我们可以发现,假设一开始最后一位是0,-1后为1,但因为有0的存在,按运算规则,该位上最终结果肯定是0的。这个时候因为-1因此我们要向高位借1,此时就有两种情况了,如果它高一位是0,按我们前面得到的结论该位运算结果肯定是0,这还不算完,它继续往上借1,直道遇到1停止,有1的那位送一个1出去,自身变为0,同时得到此次的运算结果,当然有1的那位在此次运算后也变为0.
将以上过程连起来,我们可以得出结论:有0的结果肯定是0,并且在以后的运算中也是持续为0,难逃厄运。有1的那位等于赢得了一次缓刑机会,因为每次都是只减1,因此如果它低位都是0,那么借位的传导链传到它这里就宣告结束,下一轮它包括它下面的位皆为0.如此循环,我们可以发现1的个数,就是运算暂停的次数,也就是最终的循环次数。
那么代码也就顺理成章了,先的到异或的结果,1的个数就是Hamming Distance,而如何得到1的个数这里就不说了,就是上面分析的结果。虽然这题不会,算是出师不利,但是分析答案再自己写一遍的过程也是成长的过程,后续题目即使都不会也没关系(这个有点过分),都弄懂,多刷几遍肯定会有很大收获的。
下面就是最终的代码,结束这篇文章:
[cc lang=”java”]
public static int hammingDistance(int x, int y) {
int res = 0, exc = x ^ y;
boolean flag = (exc == 0) ? false : true;
while (flag) {
++res;
exc &= (exc – 1);
if (exc == 0) {
flag = false;
}
}
return res;
}
[/cc]
2 thoughts on “出师不利的leetCode之旅,意料之中的艰难升级路”
背景和自黑两大段,一点也不简单呐
又黑我…