巧解一道阶乘排序题

今天,介绍一道在本计算机考试书上的阶乘排序(就是将一个列表长度的阶乘种的方式的排列组合输出)题。
下面我们直接看题:
在1~49中任意选择7个数,将这7个数的所有排列可能性全部输出。例如:[1,2,3]的所有输出有[2,1,3];[2,3,1];[3,2,1];[3,1,2];[1,3,2];[1,2,3].


这道题的关键是要找到一个排序的规律,在这里我不介绍各种排序的算法了(其实我也不是很懂o(╥﹏╥)o),只讲自己观察出来的一种规律。
首先,让我们把[1,2,3]的排序所有可能写下来:
这里写图片描述
这下,我们就能很容易看到这个规律了,其实,只要我们遇到这类题目,使用列举法或假设法都很好的解决问题。正如题目要求的7个,但是,这里我们使用3个数来理解这个问题就变得很简单了。下面我们再来看一张图,就了解这个规律了:
这里写图片描述
我们只关注一件事,“1”它怎么变动的,我们就能很容易的知道如何解决这道题了。其实,就是简单的将前一个数与后一个数交换位置。且这种交换是循环的,意思是当“1”从头交换到了尾就是一个循环,因为,它没有办法再继续这种交换了。然后,它再从尾交换到头,实现第二个循环。到此,我们已经明白这个规律了。
但是,还有一个问题,怎么确定不同的排序的循环呢?
然后,我们再来延伸,同样寻找规律。在分别列出了2、3、4、5个数时,它的循环数。
这里写图片描述
咋一看感觉是没有什么规律,但是,当我们将每个数的阶乘写出来了,就可以看出来其实规律还是挺容易发现的。
这里写图片描述
现在,我们就将这道题的一个规律找出来了,下面,我们就用代码来实现它:

# 首先要导入reduce累积函数,因为我使用的是python3,所以在functools库中。
from functools import reduce
# 定义一个两两交换的排序函数。
def sort_two(lis):
    length = len(lis)
    # 定义一个循环初始值
    count = 1
    # 计算阶乘
    counts = reduce(lambda x, y: x*y, range(1, length+1))
    # 计算循环数
    lim = counts/(length-1)
    while count <= lim:
        count += 1
        if not isinstance(lis, list):
            return "Please number in list"
        for i in range(length-1):
            one = lis[i]
            two = lis[i+1]
            lis[i] = two
            lis[i+1] = one
            print(lis)



if __name__ == "__main__" :
    lis = [1, 2, 3, 4]
    sort_two(lis=lis)

输出结果:
[2, 1, 3, 4]
[2, 3, 1, 4]
[2, 3, 4, 1]
[3, 2, 4, 1]
[3, 4, 2, 1]
[3, 4, 1, 2]
[4, 3, 1, 2]
[4, 1, 3, 2]
[4, 1, 2, 3]
[1, 4, 2, 3]
[1, 2, 4, 3]
[1, 2, 3, 4]
[2, 1, 3, 4]
[2, 3, 1, 4]
[2, 3, 4, 1]
[3, 2, 4, 1]
[3, 4, 2, 1]
[3, 4, 1, 2]
[4, 3, 1, 2]
[4, 1, 3, 2]
[4, 1, 2, 3]
[1, 4, 2, 3]
[1, 2, 4, 3]
[1, 2, 3, 4]

一道很有意思的规律题,感觉自己又回到了高中做数学找规律的题的时候,真是非常享受的一件事情(^▽^)。但是,自己关于算法的学习也是冰山一角,再接再厉吧!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值