zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
  • 相关阅读:
    数字以万做单位——Java
    创建二维码工具类——Java
    Java 截取指定长度的字符串
    堆排序
    context:component-scan 的使用说明
    @Autowired @Resource @Qualifier的区别
    声明对象和创建对象的区别
    maven 命令
    maven 创建
    maven pom.xml文件
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14288916.html
Copyright © 2011-2022 走看看