一.題目描述spa
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字以及條件判斷語句 (即三元運算符,A? B : C)blog
二.題解遞歸
雖然求和問題自己很容易,但加上這麼多限制條件的話,整個問題彷佛就不那麼簡單了。《劍指offer》雖然給出了四種解決方法,但這四種方法都是基於C++的語言特性求解的,並非通用的解法。因此,本文旨在給出通用的解法。首先,根據以上的限制條件,能夠考慮的角度只有兩種(我的見解)一個是遞歸,另外一個是位運算。從位運算的角度來考慮的話,能夠利用相似快速冪的思想,可是這個角度不容易想到,且實現比較麻煩(可參考牛客網討論區 馬克的答案)。另外一個角度就是遞歸,若是沒有限制條件的話,使用遞歸的代碼以下:it
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進行判斷。這個特性就是所謂的與操做符的短路特性。根據這個特性,很容易想到改進後的代碼:io
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,因此定義一個布爾型的變量最爲合適。class