劍指offer系列-面試題64. 求1+2+…+n(python)

1. 題目

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

2. 解題思路

詳情見 面試題64. 求 1 + 2 + … + n(邏輯符短路,清晰圖解)

1~n的加和,這很明顯可以用高斯求和公式,sum = n * (n+1) / 2。
因爲不能用這些語句,所以迭代、動態規劃、遞歸都不能用。
關鍵是如何計算 n * (n+1), n*(n+1) = n2 + n,所以只要能求出n 2 即可。

2.1 使用庫函數

使用python中的庫函數math.pow(),計算n2 ,用>>1 來計算除以2。

2.2 邏輯符短路

使用邏輯符短路來替代遞歸的基線條件,實現終止遞歸。

在python中,A and B和A or B 這兩個邏輯表達式的值不爲True或者False,而是A或者B的值。

python中的與(and)、或(or)、非(not)與java和c的不同之處在於

A and B:

若A爲假(如:False, 0, [], {}, ""等),則短路(不用再判斷B是否爲真,整個邏輯表達式已經爲False了),表達式的值爲A的值。
若A爲真,則繼續判斷B的值,但是不管邏輯表達式是真還是假,表達式的值都爲B的值,而不是True或者False。

A or B:

若A爲假(如:False, 0, [], {}, ""等),則繼續判斷B的值,不管最後邏輯表達式是真還是假,表達式的值都B的值。
若A爲真,則短路(不用在判斷B的值是真還是假了,整個邏輯表達式已經爲True了),表達式的值爲A的值。

3. 代碼實現

3.1 使用庫函數

import math

class Solution:
    def sumNums(self, n: int) -> int:
        """
        (n * (n+1)) // 2, n 和 n+1一定有一個是偶數,能夠被2除盡的
        --> (n*(n+1))>>1
        """
        # 使用庫函數,但是本質是否仍然用了乘除或者條件判斷語句??
        return (n + int(math.pow(n, 2))) >> 1

3.2 邏輯符短路

class Solution:
    def __init__(self):
        self.res = 0
    def sumNums(self, n: int) -> int:
        n > 1 and self.sumNums(n - 1)
        self.res += n
        return self.res

3.3 優化

class Solution:
    def sumNums(self, n: int) -> int:
    	"""
    	python中的與(and)、或(or)、非(not)與java和c的不同之處在於
		
		A and B: 若A爲False或其他空值(如:0, [], {}, ""等),則短路(不用再判斷B是否爲真,整個邏輯表達式已經爲False了)
		A or B:

    	"""
		return n and (n + self.sumNums(n-1))

4. 總結

邏輯運算符短路原則,有學到新東西了。而且還能如此將邏輯運算符與遞歸相結合,真是非常巧妙的思想。

5. 參考文獻

[1] 劍指offer叢書
[2] 劍指Offer——名企面試官精講典型編程題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章