python練習例項1
阿新 • • 發佈:2018-12-18
題目:有四個數字:1、2、3、4,能組成多少個互不相同且無重複數字的三位數?各是多少?
來看第一種解法
1 num = [1, 2, 3, 4] 2 """ 3 根據題中'互不相同'要求,建立一個集合(去重),存放三位數 4 注意{}僅用於建立空字典!set()函式用來建立集合 5 """ 6 s = set() 7 # 遍歷整個列表三次,組成三位數 8 for i in num: 9 for j in num: 10 # 去掉與i重複的數字 11 if j !=i: 12 for k in num: 13# 去掉與i,j重複的數字 14 if k != j and k != i: 15 n = 100*i + 10*j + k 16 # 注意集合新增元素的方法為add和update 17 s.add(n) 18 print("無重複的三位數個數:", len(s)) 19 print("分別是:", s)
這種解法時間複雜度為O(n2), 其中的列表可以換成range生成器
1 s = set() 2# 遍歷整個列表三次,組成三位數 3 for i in range(1, 5): 4 for j in range(1, 5): 5 # 去掉與i重複的數字 6 if j !=i: 7 for k in range(1, 5): 8 # 去掉與i,j重複的數字 9 if k != j and k != i: 10 n = 100*i + 10*j + k 11 # 注意集合新增元素的方法為add和update12 s.add(n) 13 print("無重複的三位數個數:", len(s)) 14 print("分別是:", s)
以上兩種解法都可以改成列表推導式的形式,如下,這種形式看上去簡潔,但如果出錯了排查起來比較困難,一般不推薦使用
lst = [100*i + 10*j + k for i in num for j in num for k in num if (i != j and j != k and k != i)]
第三種方法比較野路子,先確定最終數的範圍,然後一個一個判斷,當然這種效率是極低的
1 s = set() 2 # 縮小範圍,三位數肯定在123和433之間 3 for i in range(123, 433): 4 # 個位數字 5 a = i%10 6 # 十位數字 7 b = (i%100)//10 8 # 各位數字 9 c = (i%1000)//100 10 if a != b and b != c and a != c and 0 < a < 5 and 0 < b < 5 and 0 < c < 5: 11 s.add(i) 12 print("無重複的三位數個數:", len(s)) 13 print("分別是:", s)
第四種方法是運用python的內建函式permutations,其語法格式為:
permutations(iterable[, r]),返回一個長度為r的元組
程式碼如下:
from itertools import permutations # permutations返回3位長度的元組,permutations意為交換 s = set() for i in permutations([1, 2, 3, 4], 3): k = '' for j in range(0, len(i)): k = k + str(i[j]) s.add(int(k)) print("無重複的三位數個數:", len(s)) print("分別是:", s)
總結
第一、二種方法比較接近,都是for迴圈巢狀加判斷求解,第三種方法比較另類,先判斷一個大致範圍再遍歷,第四種方法運用python內建的permutations函式直接生成包含3個數字的元組。綜合來看,第四種方法更簡潔