Medium | 剑指 Offer 64. 求1+2+…+n | 位运算

剑指 Offer 64. 求1+2+…+n

1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

限制:

  • 1 <= n <= 10000

解题思路

这是一道考验知识储备的题目。高斯小学就告诉我们, 首尾相加乘以个数除以二结果就出来了。我们小学就知道, 这是最简单最快捷的方法。现在题目把路堵死了, 那该怎么解决。毫无疑问, 这道题的所有解决办法都是效率不高的办法, 所以这道题并不追求效率。目的就是看你肚子有多少知识储备, 看你能想出多少种解决办法。

先看能使用的运算符, 把运算符数一遍, 还可以用的运算符有加法, 减法, 与, 或, 非, 移位。

方法一:递归

public int sumNums(int n) {
    boolean flag = n > 0 && (n += sumNums(n - 1)) > 0;
    return n;
}

方法二: 俄罗斯农民乘法

这道题第一反应就是 n * (n + 1) / 2,除2可以通过移位来实现 n * (n + 1) >> 1,那么乘法有没有办法通过其他方式实现呢?只使用加法和移位就可以实现, 以下是原理。

A * B可以把B写作二进制的形式, 即B = 2^0 + 2^1 + 2^2 + ... 2^n 的形式, 那么A * B 可以写作 A * 2^0.... A* 2 ^ n, 当然这里面有些系数是0, 我这图方便没有写。所以通过二进制表示和位运算, 可以先看B有有哪些位是1的, 对于是1的位, 将A左移, 左移的距离就是这个位数。然后将这些左移之后的数字进行相加即可。理论上有32个位, 要将32个位逐个判断进行相加。题目规定了N不超过10000, 所以也就14位。下面是硬编码的代码.

class Solution {
    public int sumNums(int n) {
        int ans = 0, A = n, B = n + 1;
        boolean flag;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        flag = ((B & 1) > 0) && (ans += A) > 0;
        A <<= 1;
        B >>= 1;

        return ans >> 1;
    }
}
原文地址:https://www.cnblogs.com/chenrj97/p/14288916.html