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

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

 

 

 

转载于:https://www.cnblogs.com/zzliu/p/10134740.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值