LintCode_day1

1.a + b问题

例如:0b01001010 + 0b00110011
0100 1010
0011 0011
首先,计算不需要进位的地方,a ^ b之后:
0111 1101
然后计算需要进位的地方,a & b之后:
0000 0010
接着对需要进位的地方进行进位 <<1:
0000 0100
此时应该计算的值就变成了:
0111 1101
0000 0100
重复上面的步骤,可以得出:0b01111101
因为(a & b) << 1,也就是进位不为0决定了要不要循环,不需要进位直接抑或就行了,所以:

	int Add(int num1,int num2) { 
        if(0 == (num1 & num2)) {
            return num1 ^ num2;
        }
         
        return Add(num1 ^ num2, (num1 & num2) << 1);
     }

2.尾部的零

样例:11! = 39916800,结果为2.
把1 x 2 x 3 x …看成 1 x 2 x3 x4 x 5 x (2 x 3) x…
最后每一个2 x 5都将产生一个0,又因为2的个数总是多于5的个数的,所以其实0的个数就是5的个数,此题便成了找1~11由5组成的数的个数。

  long long trailingZeros(long long n) {
        long sum = 0;
        while (0 != n){
            sum += n / 5;
            n /= 5;
        }
                
        return sum;
    }

3.计算数字k在0到n中的出现的次数,k可能是0~9的一个值

输入:
k = 1, n = 12
输出:
5
解释:
在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 中,我们发现 1 出现了 5 次 (1, 10, 11, 12)(注意11中有两个1)

方式一:遍历统计

遍历所有的数,计算每个数中查询数出现的次数

int digitCounts(int k, int n) {
        int count = 0;
        if (k == 0) {
            count = 1;
        }
        for (int i = 1; i <= n; i++) {
            int number = i;
            while (number > 0) {
                if (number % 10 == k) {
                    count += 1;
                } 
                number /= 10;
            }
        }
        
        return count;
    }

方式二:按位统计

主要原理:每10个数,必定出现一次查询数,所以直接统计每位出现查询数的次数,比如:
k = 3, n = 2544
在个位上:出现254 + 1次,1是个位数字4单独处理2543
在十位上:出现25 + 1次,1是十位数字4单独处理253x
在百位上:出现2 + 1次,…

  int digitCounts(int k, int n) {
      int count = 0 , x;
      if (k == 0 && n == 0) count = 1;
      for (int i = 1;x = n / i;i *= 10) {
          int high = x / 10;
          if (k == 0) {
              if (high) high--;
              else {
                  count++;
                  break;
              }
          }
          count += high * i;
          int current = x % 10;
          if (current > k) count += i;
          else if (current == k) count += n - x * i + 1;
      }
      return count;
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值