1、给出两个整数a和b, 求他们的和, 但不能使用 +
等数学运算符。
难点:使用逻辑求两数的和
分析:先不考虑进位的相加得到的结果a,再只考虑进位有哪些将其左移一位得到b,最后将a、b相加(即重载)。
以3 + 5为例 3的二进制为 1 1,5的二进制为 1 0 1
可以这样做:1先给这两个数加起来不考虑进位,这样得到的结果为 1 1 0,会发现与^(异或符号)得到的结果相同,于是先给两个数做^运算;
2、接下来考虑进位,两个二进制数相加会有这么几种情况 1 1,0 0, 1 0, 0 1除第一种情况外其他情况均不产生进位,而1 1两数相加进1,结果得0,可以这样做先将两个数做&运算,再将结果左移1位,这样就模拟了进位
3、将第1步得到的没进位的和 和第2步的进位相加便是结果,下面是代码
{
if (num2==0) retur num1; //注意:这里的if条件语句是判断如果没有进位后,那么num1即为最后的结果,因此返回num1即可。它是终止条件。
int num3=num1^num2;
int carry=(num1&num2)<<1;
return add(num3,carry);
因此最后方法为如下,被注释的三行为网上的答案。
class Solution {
public:
/**
* @param a: An integer
* @param b: An integer
* @return: The sum of a and b
*/
int aplusb(int a, int b) {
if (b==0) return a;
int c=a^b;
int carry=(a&b)<<1;
return aplusb(c,carry);
// int c=a&b;
// int d=a^b;
// return c==0?d:aplusb(c<<1,d);
}
};
2、尾部的零。
分析:最后尾数为零的数都是5和偶数相乘的结果,因此只需计算有n里面有多少个5即可。
程序代码如下:
class Solution {
public:
/*
* @param n: A long integer
* @return: An integer, denote the number of trailing zeros in n!
*/
long long trailingZeros(long long n) {
long long result=0;
while(n/5>0)
{
result=result+n/5;
n/=5;
}
return result;
}
};
3、统计数字
class Solution {
public:
/*
* @param : An integer
* @param : An integer
* @return: An integer denote the count of digit k in 1..n
*/
int digitCounts(int k, int n) {
int a[n+1];int result=0; //使用数组存储0~n的每个数,方便枚举测试,result用于记录结果
for(int i=0;i<=n;i++) a[i]=i; //将0~n存入a[n+1]数组
if(k==0) result=1; //当k==0时,如果按照下面的算法,会漏下a[i]是0的情况,因此在这里先加一
for(int i=0;i<=n;i++) //1~n每个数都与k值比较
{
int number=a[i];
while(number!=0)
{
if ((number%10)==k) result++;
number/=10;
}
}
return result;
}
};
4、丑数Ⅱ
首先最容易想到的方法就是暴力破解,思路非常简单,首先除2,直到不能整除为止,然后除5到不能整除为止,然后除3直到不能整除为止。最终判断剩余的数字是否为1,如果是1则为丑数,否则不是丑数。
代码如下:
- class Solution {
- public:
- /*
- * @param n an integer
- * @return the nth prime number as description.
- */
- int nthUglyNumber(int n) {
- // write your code here