• 《剑指offer(第二版)》面试题64——求1+2+...+n


    一.题目描述

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

    二.题解

      虽然求和问题本身很容易,但加上这么多限制条件的话,整个问题似乎就不那么简单了。《剑指offer》虽然给出了四种解决方法,但这四种方法都是基于C++的语言特性求解的,并不是通用的解法。所以,本文旨在给出通用的解法。首先,根据以上的限制条件,可以考虑的角度只有两种(个人看法)一个是递归,另一个是位运算。从位运算的角度来考虑的话,可以利用类似快速幂的思想,但是这个角度不容易想到,且实现比较麻烦(可参考牛客网讨论区 马克的答案)。另一个角度就是递归,如果没有限制条件的话,使用递归的代码如下:

    int Sum_Solution(int n) {
            int sum = n;
            if(n == 0)
                return sum;
            return sum + Sum_Solution(n - 1);
        }
    

    这段代码主要有两个关键点:递归的终止条件和如何进行下一步递归。回到原问题上,由于题目要求不能使用if来进行条件判断,所以我们要通过其他操作来实现n == 0的判断,最容易想到的就是&&操作符,它同样地能进行条件判断,这主要得益于它的一个特性:即A&&B的话,只有条件A满足的话,才会对条件B进行判断;否则就不会对条件B进行判断。这个特性就是所谓的与操作符的短路特性。根据这个特性,很容易想到改进后的代码:

    int Sum_Solution(int n) {
            int sum = n;
            bool flag = (n > 0) && ((sum += Sum_Solution(n-1)) > 0);//第一个条件(n > 0)相当于终止条件
            return sum;
    }

    这段代码时间复杂度为O(n)。主要通过&&操作符,实现了与上段代码同样的操作,它们的逻辑本质上是一样的。只有当n>0的时候,sum才会进行下一次递归,否则就不会递归。又由于&&操作的返回的结果是0或1,所以定义一个布尔型的变量最为合适。

  • 相关阅读:
    【拓扑排序】【堆】CH Round #57
    【数论】【筛法求素数】【欧拉函数】bzoj2818 Gcd
    【数论】【枚举约数】【欧拉函数】bzoj2705 [SDOI2012]Longge的问题
    【暴力】vijos P1897 学姐吃牛排
    【kruscal】【最小生成树】【并查集扩展】bzoj3714 [PA2014]Kuglarz
    【set】bzoj2761 [JLOI2011]不重复数字
    【尺取法】【Multiset】bzoj1342 [Baltic2007]Sound静音问题
    【神奇の做法】bzoj2456 mode
    【博弈论】bzoj2463 [中山市选2009]谁能赢呢?
    【set】bzoj3715 [PA2014]Lustra
  • 原文地址:https://www.cnblogs.com/wangkundentisy/p/9374215.html
Copyright © 2020-2023  润新知