楊輝三角Python解法1.0
楊輝三角Python解法1.1
Python楊輝三角打印最樸素解法:把前兩項作爲特殊項,這個算法可以集中練習索引的邊界問題。
>>> n = 6
>>> triangle = [[1],[1,1]]
# 這裏留白分段,好的書寫習慣讓編碼便於閱讀
>>> for i in range(2,n):
>>> cur = [1]
>>> pre = triangle[i-1]
>>> triangle.append(cur)
>>> for j in range(i-1):
>>> cur.append(pre[j]+pre[j+1])
>>> cur.append(1)
# triangle.append(cur)
["{}".format(i) for i in triangle]
楊輝三角Python打印解法1.2
解法1的升級完善版本,所有項目自動生成。
>>> n = 6
>>> triangle = [] # 容器裏面放各個行
# 這裏留白分段,好的書寫習慣讓編碼便於閱讀
>>> for i in range(n):
>>> cur = [1]
>>> triangle.append(cur) # 引用數據類型cur,先append後修改和先修改後append效果一樣
>>> pre = triangle[i-1]
>>> if i ==0:
>>> continue # continue的用法!
>>> for j in range(i-1):
>>> cur.append(pre[j]+pre[j+1])
>>> cur.append(1)
# print(cur)
# triangle.append(cur) 引用數據類型cur,先append後修改和先修改後append效果一樣
>>> ["{}".format(i) for i in triangle]
Python楊輝三角打印解法1.3
如上兩個版本必須要生成第1-n行,降低空間複雜度。解法3只用2行循環,便實現第n行的生成。
這個方法好嗎?
- 優點:從解法1-2的多行到現在的雙行,降低了空間複雜度;
- 缺點:內存在大量丟棄計算出來的數據,而大量丟棄計算出來的數據的編程方法,一般是需要反思的。
>>> n = 6
# >>> triangle = [] # 不用這個容器了,存儲所有了,註釋不用。
>>> pre = []
>>> cur = []
# 這裏留白分段,好的書寫習慣讓編碼便於閱讀
>>> for i in range(n):
>>> cur = [1]
>>> if i == 0:
# print(cur)
>>> pre = cur
>>> continue # continue的用法!
>>>
>>> for j in range(i - 1):
>>> cur.append(pre[j] + pre[j + 1])
>>> cur.append(1)
>>> pre = cur # 新pre產生,舊pre引用計數清零;在適當的時機,內存清理它。
>>> print(["{}".format(i) for i in cur])
['1', '5', '10', '10', '5', '1']
# 解法3的近似體
>>> n = 6
# >>> triangle = [] # 不用這個容器了,存儲所有了,註釋不用。
>>> pre = [1]
>>> # 這裏留白分段,便於閱讀
>>> for i in range(n):
>>> cur = [1]
>>> if i == 0:
>>> # print("cur",cur)
>>> continue # continue的用法!
>>> if i == 1:
>>> cur.append(pre[i-1])
>>> # print("i=1 cur", cur)
>>> for j in range(i - 1):
cur.append(pre[j] + pre[j + 1])
>>> cur.append(1)
>>> pre = cur
# print("pre", pre)
>>> print(["{}".format(i) for i in cur])
['1', '5', '10', '10', '5', '1']
Python楊輝三角打印解法1.4
在3基礎上做優化,將語句進行潤色;效率上與Python楊輝三角打印解法3是一樣的沒有區別:
>>> n = 6
>>> pre = []
# 這裏留白分段,好的書寫習慣讓編碼便於閱讀
>>> for i in range(n):
>>> cur = [1]
>>> if i != 0: # 把囉嗦的if =0 ,換成語句更通順的邏輯。
>>> for j in range(i - 1):
>>> cur.append(pre[j] + pre[j + 1])
>>> cur.append(1)
>>> pre = cur
>>> print(["{}".format(i) for i in cur])
['1', '5', '10', '10', '5', '1']
Python楊輝三角打印解法1.5
用一次開闢列表index的方法
>>> n = 6 # 我們從n=1開始演算
>>> for i in range(n):
>>> cur = [1]*(i+1) #我們這次不再賦值None,而是賦值1,這樣就省得再修改首尾的1了
>>> for j in range( i - 1): #j=2```3
>>> cur[j+1]=pre[j+1]+pre[j] # 這裏因爲cur的下標變成了j+1,所以pre的小標對應的也要各增加1
>>> print("cur in this loop ",cur)
>>> pre = cur
>>> print(["{}".format(i) for i in cur])
cur in this loop [1]
cur in this loop [1, 1]
cur in this loop [1, 2, 1]
cur in this loop [1, 3, 3, 1]
cur in this loop [1, 4, 6, 4, 1]
cur in this loop [1, 5, 10, 10, 5, 1]
['1', '5', '10', '10', '5', '1']
2.0 楊輝三角的Python算法(補0法):
2.1 楊輝三角的Python補0法,append法
通過觀察,如果在前面一行的兩端補0,後面一行。
編碼中規避了在index[0]的位置補0,有利於規避線性數據結構的效率損失
>>> n = 6
>>> pre = [1]
>>> for i in range(1,n):
>>> cur = []
>>> pre.append(0)
>>>
>>> for j in range(i+1):
>>> cur.append(pre[j-1]+pre[j+0]) # 這裏使用了負索引的技巧!
>>> # print("this cur",cur)
>>> pre = cur
>>> print(cur)
[1, 5, 10, 10, 5, 1]
2.2 楊輝三角的Python補0算法
一般來說,一次性開闢內存空間。一般來說,頻繁的append效率沒有一次性擴展一定大小好。
如上“2.1 楊輝三角的Python補0法”中,append的方法要每次追加,那效率就不如一次性生成效率高;本部分升級將cur使用 cur= [None]*(i+1)一次性開闢所有列表元素,從而提高了Python代碼的效率。
這是一種Python編程提高效率的技巧,對於列表來說,如果知道未來列表有多大,而且你即將逐個將其佔滿的話,不如直接一次性開闢好這麼大的空間。雖然Python append實際上因爲做了優化,所以當使用append追加時候,Python在最後的元素之後已經預留了一定空間,所以這個技巧實操起來可能並不一定可以感受到效率提高,但這是一種很好的編程思想和習慣。
當然,如果你並無法知道未來將用多大的列表,那就只能用append了。
>>> n = 6
>>> pre = [1]
>>> for i in range(1, n):
>>> pre.append(0) # 補0:這裏注意無需補2個0;並且規避在index[0]的補零有利於提高效率 # pre =[1,0]```pre=[1,1,0]```pre=[1,2,1,0]
>>> cur = [None]*(i+1)
>>> print("----")
>>> for j in range(i+1):
>>> cur[j]=pre[j-1]+pre[j]
>>> pre = cur #[1,2,1]
>>> print("cur in this loop",cur)
>>> print(["{}".format(i) for i in cur])
----
cur in this loop [1, 1]
----
cur in this loop [1, 2, 1]
----
cur in this loop [1, 3, 3, 1]
----
cur in this loop [1, 4, 6, 4, 1]
----
cur in this loop [1, 5, 10, 10, 5, 1]
['1', '5', '10', '10', '5', '1']
3.0 楊輝三角的Python算法:對稱算法
3.1 楊輝三角的Python算法:對稱算法
對稱算法通過使用列表的對稱,將計算量縮減了一般。
同時,我們使用1.0的方法,將所有行都不視爲特例。
且不使用2.0的補0法(因爲補0法是一個很好的列表練習,但效率並不高),但將其中的一次性開闢列表空間的思想應用。
>>> n = 6 # 我們從n=1開始演算
>>> for i in range(n):
>>> cur = [1]*(i+1) #我們這次不再賦值None,而是賦值1,這樣就省得再修改首尾的1了
>>> for j in range( i//2): #這裏要找計算幾次的規律: 1--0;2--1;3--1;4--2;5--2
>>> cur[j+1] = pre[j+1]+pre[j]
>>> cur[-(j+1)-1]= cur[j+1] #列表的對稱位索引,值得記憶!!!
#### 等於 cur[-j-2] = cur[j+1]
>>> print("cur in this loop ",cur)
>>> pre = cur
>>> print("對稱算法3.1",["{}".format(i) for i in cur])
cur in this loop [1]
cur in this loop [1, 1]
cur in this loop [1, 2, 1]
cur in this loop [1, 3, 3, 1]
cur in this loop [1, 4, 6, 4, 1]
cur in this loop [1, 5, 10, 10, 5, 1]
對稱算法3.1 ['1', '5', '10', '10', '5', '1']
3.2 楊輝三角的Python算法:對稱算法的完善
3.1有一個小優化點,當行是奇數時候,中心點被賦值兩次,浪費了內存
>>> n = 6 # 我們從n=1開始演算
>>> for i in range(n):
>>> cur = [1]*(i+1) #我們這次不再賦值None,而是賦值1,這樣就省得再修改首尾的1了
>>>
>>> for j in range(i//2): #這裏把上版的range(i//2)向右平移1,不影響計算次數,
>>> #但i和j在中間點上就有了二倍關係
>>> # i =2, j=0, middle =1 重複
>>> # i =3, j=0,middle =1, 不重複賦值
>>> # i =4, j=0,1,middle =2,重複賦值
>>> value = pre[j+1] +pre[j]
>>> cur[j+1] = value
>>>
>>> print("cur in this loop ",cur)
>>> pre = cur
>>>
>>> print("完美的對稱算法3.1",["{}".format(i) for i in cur])
cur in this loop [1]
cur in this loop [1, 1]
cur in this loop [1, 2, 1]
cur in this loop [1, 3, 1, 1]
cur in this loop [1, 4, 4, 1, 1]
cur in this loop [1, 5, 8, 1, 1, 1]
完美的對稱算法3.1 ['1', '5', '8', '1', '1', '1']
>>> n = 6 # 我們從n=1開始演算
>>> for i in range(n):
>>> cur = [1]*(i+1) #我們這次不再賦值None,而是賦值1,這樣就省得再修改首尾的1了
>>>
>>> for j in range(1, i//2+1): #這裏把上版的range(i//2)向右平移1,不影響計算次數,
>>> #但i和j在中間點上就有了二倍關係
>>> # i =2, j=0, middle =1 重複
>>> # i =3, j=0,middle =1, 不重複賦值
>>> # i =4, j=0,1,middle =2,重複賦值
>>> value = pre[j-1] +pre[j]
>>> cur[j] = value
>>> if i == 2*j:
>>> pass
>>> else:
>>> cur[-j-1]=value
>>>
>>> print("cur in this loop ",cur)
>>> pre = cur
>>>
>>> print("對稱算法3.1",["{}".format(i) for i in cur])
cur in this loop [1]
cur in this loop [1, 1]
cur in this loop [1, 2, 1]
cur in this loop [1, 3, 3, 1]
cur in this loop [1, 4, 6, 4, 1]
cur in this loop [1, 5, 10, 10, 5, 1]
對稱算法3.1 ['1', '5', '10', '10', '5', '1']
最後做語法潤色,把i==2"j的判斷,修改爲if i!==2*j
>>> n = 6 # 我們從n=1開始演算
>>> for i in range(n):
>>> cur = [1]*(i+1) #我們這次不再賦值None,而是賦值1,這樣就省得再修改首尾的1了
>>>
>>> for j in range(1, i//2+1): #這裏把上版的range(i//2)向右平移1,不影響計算次數,
#但i和j在中間點上就有了二倍關係
# i =2, j=0, middle =1 重複
# i =3, j=0,middle =1, 不重複賦值
# i =4, j=0,1,middle =2,重複賦值
>>> value = pre[j-1] +pre[j]
>>> cur[j] = value
>>> if i!= 2*j:
>>> cur[-j-1]=value
>>>
>>> print("cur in this loop ",cur)
>>> pre = cur
>>> print("對稱算法3.1",["{}".format(i) for i in cur])
cur in this loop [1]
cur in this loop [1, 1]
cur in this loop [1, 2, 1]
cur in this loop [1, 3, 3, 1]
cur in this loop [1, 4, 6, 4, 1]
cur in this loop [1, 5, 10, 10, 5, 1]
對稱算法3.1 ['1', '5', '10', '10', '5', '1']