【嘎】将数字变成 0 的操作次数
题目:
给你一个非负整数 num
,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。
示例 1:
输入:num = 14
输出:6
解释:
步骤 1) 14 是偶数,除以 2 得到 7 。
步骤 2) 7 是奇数,减 1 得到 6 。
class Solution { public int numberOfSteps (int num) { return getCount(num, 0); } public int getCount(int num, int count) { if (num == 0) { return count; } if (num % 2 == 1) { num--; count++; } else { num = num /2; count++; } return getCount(num, count); } }
步骤 3) 6 是偶数,除以 2 得到 3 。
步骤 4) 3 是奇数,减 1 得到 2 。
步骤 5) 2 是偶数,除以 2 得到 1 。
步骤 6) 1 是奇数,减 1 得到 0 。
示例 2:
输入:num = 8
输出:4
解释:
步骤 1) 8 是偶数,除以 2 得到 4 。
步骤 2) 4 是偶数,除以 2 得到 2 。
步骤 3) 2 是偶数,除以 2 得到 1 。
步骤 4) 1 是奇数,减 1 得到 0 。
示例 3:
输入:num = 123
输出:12
提示:
0 <= num <= 10^6
解答:
class Solution { public int numberOfSteps (int num) { return getCount(num, 0); } public int getCount(int num, int count) { if (num == 0) { return count; } if (num % 2 == 1) { num--; count++; } else { num = num /2; count++; } return getCount(num, count); } }
我写的有些混乱 ,其实也可以在操作外面加上 if (num != 0) , 然后最后return count的。
其他解答:
1. 递归
class Solution { private int count = 0; public int getCount(int num) { if (num != 0) { count++; if ((num & 1) != 0) { // 把num转换成二进制数与1相与,每一位相同就是1,不同就是0 getCount(num & -2); } else { getCount(num >> 1); // 偶数,右移一位,就相当于是除以二 } } return count; } }
一个整数a, a & 1 这个表达式可以用来判断a的奇偶性。二进制的末位为0表示偶数,最末位为1表示奇数。使用a%2来判断奇偶性和a & 1是一样的作用,但是a & 1要快好多。
在计算机里是只认识二进制的,我们人类用的一般是十进制,而二进制有个特点就是每一位上要么是0要么是1,还有一个特点是如果哪个位置是1,那一位的值就是2^n【^这个符号表示次方】,n就是这个1所处的位。举个例子,比如二进制“11”,它有两位,那么类比十进制“个十百千”的规律,这里的个位1(也就是最右边的1)它的值是2^0=1,它的十位就是2^1=2,所以它的总数为2+1=3。这就是二进制的计算规则。了解了这个规则之后,你可能会发现,2的n次方(n>0)肯定是偶数,只有在第0位为1时才会是奇数。
那么如何才能知道一个数的第0位为1呢?答案就是按位与,也就是“&”这个操作符,按位与就是把两个二进制数按照“1和1与为1,1和0与为0”输出结果,比如两个二进制数“11”(即十进制3)和“01”(即十进制1)按位与,结果为“01”也就是十进制1。
知道以上两点后,你应该就能理解为什么“i&1”可以判断奇偶性了吧。
一开始一直不理解按位与怎么就只有1,原来不是像乘法一样都和1按位与,而是1前面补零。
2. 用while循环 迭代,我之前一闪而过的while被脑中的递归干掉了。。。
class Solution { public int numberOfSteps (int num) { int sum=0; while(num!=0){ sum++; if(num%2==0){ num=num/2; } else{ num=num-1; } } return sum; } }