1. 程式人生 > >[演算法]發散思維能力題目

[演算法]發散思維能力題目

1. 求1+2+3+...+n

題目描述

求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。

思路

短路求值,&&邏輯與,邏輯與有個短路特點,前面為假,後面不計算。不讓用這些迴圈判斷,只能用遞迴。

程式碼

public class Solution {
    public int Sum_Solution(int n) {
        int sum = n;
        boolean res = (n > 0) && ((sum += Sum_Solution(n - 1)) > 0);
        
return sum; } }

2. 不用加減乘除做加法

題目描述

寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。

思路

首先我們可以分析人們是如何做十進位制的加法的,比如是如何得出5+17=22這個結果的。實際上,我們可以分成三步的:第一步只做各位相加不進位,此時相加的結果是12(個位數5和7相加不要進位是2,十位數0和1相加結果是1);第二步做進位,5+7中有進位,進位的值是10;第三步把前面兩個結果加起來,12+10的結果是22,剛好5+17=22。
前面我們就在想,求兩數之和四則運算都不能用,那還能用什麼啊?對呀,還能用什麼呢?對數字做運算,除了四則運算之外,也就只剩下位運算了。位運算是針對二進位制的,我們也就以二進位制再來分析一下前面的三步走策略對二進位制是不是也管用。
5的二進位制是101,17的二進位制10001。還是試著把計算分成三步:第一步各位相加但不計進位,得到的結果是10100(最後一位兩個數都是1,相加的結果是二進位制的10。這一步不計進位,因此結果仍然是0);第二步記下進位。在這個例子中只在最後一位相加時產生一個進位,結果是二進位制的10;第三步把前兩步的結果相加,得到的結果是10110,正好是22。由此可見三步走的策略對二進位制也是管用的。
接下來我們試著把二進位制上的加法用位運算來替代。第一步不考慮進位,對每一位相加。0加0與 1加1的結果都0,0加1與1加0的結果都是1。我們可以注意到,這和異或的結果是一樣的。對異或而言,0和0、1和1異或的結果是0,而0和1、1和0的異或結果是1。接著考慮第二步進位,對0加0、0加1、1加0而言,都不會產生進位,只有1加1時,會向前產生一個進位。此時我們可以想象成是兩個數先做位與運算,然後再向左移動一位。只有兩個數都是1的時候,位與得到的結果是1,其餘都是0。第三步把前兩個步驟的結果相加。如果我們定義一個函式,第三步就相當於輸入前兩步驟的結果來遞迴呼叫自己。

程式碼

public class Solution {
    public int Add(int num1,int num2) {
        if(num2 == 0){
            return num1;
        }
        return Add(num1 ^ num2, (num1 & num2) << 1);
    }
}