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

一、题目

1、题目描述

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

2、基础框架

class Solution {
    public int sumNums(int n) {

    }
}

3、原题链接

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

二、解题报告

1、递归结合逻辑运算符

1.1 思路分析

   ( 1 ) (1) (1) 由于不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C),还可以使用的只剩下位运算、逻辑运算符、加减法以及赋值。
   ( 2 ) (2) (2) 递归方法的思想是将一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,该问题可以将计算 F ( n ) F(n) F(n) 转换为 F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n) = F(n-1) + F(n-2) F(n)=F(n1)+F(n2) ,只需不断计算小问题直至达到递归终止条件为止。
   ( 3 ) (3) (3) 通常实现递归时,一般都会用条件判断语句来作为终止条件,而现在条件判断语句无法使用,因而可以利用逻辑运算符的短路性质来作为递归的终止条件。

1.2 复杂度分析

  空间复杂度: O ( n ) O(n) O(n)
  时间复杂度: O ( n ) O(n) O(n)

1.3 代码详解

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

2、快速乘

2.1 思路分析

   ( 1 ) (1) (1) 快速乘的原理是利用二进制将乘法变为加法,例如: a × b = ( x 0 × 2 0 × b + x 1 × 2 1 × b + x 2 × 2 2 × b + x 3 × 2 3 × b + ⋯ + x n × 2 n × b ) a\times b = (x_0\times2^0\times b + x_1\times2^1\times b +x_2\times2^2\times b + x_3\times2^3\times b+ \cdots + x_n\times2^n\times b) a×b=(x0×20×b+x1×21×b+x2×22×b+x3×23×b++xn×2n×b)
   ( 2 ) (2) (2) 因此,只需要得到 每一个 2 n ∗ 5 2^n * 5 2n5 以及前面的系数相乘再相加即可得到答案。
   ( 3 ) (3) (3) 该题需要利用等差数列的求和公式 S = n ( a 1 + a n ) 2 = n ( 1 + n ) 2 S = \frac {n(a_1+a_n)}{2}=\frac{n(1+n)}{2} S=2n(a1+an)=2n(1+n)
   ( 3 ) (3) (3) 因为该题条件是不允许用循环做,而题目数据 n n n 范围为 [ 1 , 10000 ] [1,10000] [1,10000],所以 n n n 二进制展开最多不会超过 14 14 14 位,我们手动展开 14 层代替循环即可,至此满足了题目的要求。

2.2 复杂度分析

  空间复杂度: O ( 1 ) O(1) O(1)
  时间复杂度: O ( log ⁡ n ) O(\log n) O(logn)

2.3 代码详解

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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值