剑指offer - 发散思维能力
1.求 1+2+3+...+n
问题描述:
求 1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句(A?B:C)。
方法一:
function Sum_Solution(n) {
// write code here
var sum = Math.pow(n, 2) + n;
return sum >> 1; //右移一位相当于除以二,相当于parseInt(sum/2)
}
方法二:递归 + 短路原理
function Sum_Solution(n) {
// write code here
var sum = n;
sum += sum && Sum_Solution(n - 1); //短路原理
return sum;
}
2.不用加减乘除做加法
问题描述:
写一个函数,求两个整数之和,要求在函数体内不得使用+ - * /四则运算符号。
解题思路:
使用位运算实现加法
- 一位加法
举例: 1 + 1 = 2
① res1 = 1 ^ 1 = 0
② res2 (1 & 1) << 1 = 10
③ res1 = res1 ^ res2 = 10
④ res2 = (res1 & res2) << 1 = 0两个基本表达式:
- 执行加法 x ^ y
- 进位操作 ( x & y ) << 1
- 二位加法
正确的加法计算:11+01 = 100 (3 + 1 = 4)
① 按位加法: res1 = 11 ^ 01 = 10
② 与运算进位: res2 = (11 & 01) << 1 = ( 01 ) << 1 = 010
③ res1 = res1 ^ res2 = 10 ^ 010 = 00
④ res2 = (10 & 10) << 1 = 100
⑤ res1 = res1 ^ res2 = 00 ^ 100 = 100
⑥ res2 = (00 & 100) << 1 = 000
输出 res1- 更高位的加法
继续推理可以得出三位数的加法只需重复的计算三次得到第一个表达式的值就是计算出来的结果
function Add(num1, num2) {
// write code here
var res1 = num1 ^ num2; //异或 不带进位的加法
var res2 = (num1 & num2) << 1; //按位与 进位
while (res2 !== 0) {
[res1, res2] = [res1 ^ res2, (res1 & res2) << 1];
}
return res1;
}