python练习实例1--------给定数字组成三位数

时间:2023-02-22 16:08:36

题目:有四个数字: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和update
12                     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个数字的元组。综合来看,第四种方法更简洁