持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
题目:本文还是有两题:
- 求
1+2+3+...+n。在运算过程中不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 - 不用加减乘除做加法。计算两数之和,要求不能使用四则运算。
解题思路
说实话,两题都是端午想放松一下,但还是要卷一篇水文,以此来迷惑颓废的心灵。。。。。毫无意外,未遂,卒~
回到本题,本题常规思路就显得没意义了,无非就是遍历数组或者使用递归的方法。但遍历数组用了for,而递归需要判断递归结束的条件,即使用了if,既然解题思路只有这两种,那肯定是从其中一种进行修改,修改的方法通过感觉是使用位运算。遍历数组显然无法修改,那可能性只能是递归了,我们首先来看一下常规递归怎么解决本题:
public int sumNums(int n) {
if(n<=0) return 0;
return sumNums(n-1) + n;
}
此方法不满足条件的只有第一个判断的地方,我们需要判断n是否满足条件从而决定是否向下继续执行,即只需要在不满足条件时阻塞递归的n-1即可。
通过这个特性,可以想到截断位运算,当中为的时候,将不会判断,但我们需要让的表达式完成加后的结果,可得代码如下:
public int sumNums(int n) {
boolean flag = n >=0 && (n += sumNums(n-1))>0;
return n;
}
接下来来看第二问,计算两数之和,不使用加减法,本题还是使用位运算,需要知道的前缀知识是:
- 两个数非进位和,则采用异或运算。
- 两个数进位,则采用与运算+左移一位
可得代码如下:
public int add(int a, int b) {
if(a == 0) return b;
int base = a ^ b;
int up = a & b;
return add(up<<1,base);
}