python1到n的所有排列_网易 大题第一道 小易把1到n的所有排列按字典序列排成一排...

本文介绍了如何解决网易校招算法工程师笔试题中的一道问题,该问题要求根据给定的1到n的排列,找出其在所有排列中的倒数第Q个排列。文中提供了两种解决方案,第一种方法通过列举所有排列并计算索引,时间复杂度过高;第二种方法利用排列的对称性,仅需5行核心代码,提高了效率。
摘要由CSDN通过智能技术生成

2019年8月3日,网易校招 算法工程师岗位 大题第一道

刚才笔试,一道题没做出来, 第一道题,写出来了,时间复杂度还太大,测试超时了。很不甘心,于是交卷后又重新思考了一下。其实很简单

题目:有一天,小易把1到n的所有排列按字典序列排成一排。小易从中选出了一个排列,假设它是正数第Q个排列,小易希望你能回答他倒数第Q个排列是什么。

例如1到3的所有排列是:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

若小易选出的排列是 1 2 3 ,则Q=1,而你应该输出排列3 2 1

输入描述:

第一行数字n,表示排列长度接下来一行n个数字,表示选出的排列1<= n <= 300000

输出描述:

一行n个数字,表示所求的排列。

示例1:

输入

3

1 2 3

输出:

3 2 1

示例2:

输入

5

3 1 5 2 4

输出:

3 5 1 4 2

方法一: 这是我笔试时写的。如果按照题目的思路,你需要先知道所有排列的可能性,然后安装索引Q输出。

也就是

1捕获输入;

2对所给输入进行排序,把3 1 5 2 4 重新排序成 1 2 3 4 5  ,12345也是所有排列组合的第一种

3 罗列所有排列组合的可能性,12345、12354、12435、12453这种

4计算Q,你要知道3 1 5 2 4 是所有排列组合中的第几种,这里Q是第53,索引是52.

5输出结果,然后输出【所有排列可能性】中倒数第53个

这里插一句,在线笔试题用的牛客网,编程时是可以切换页面的。我们不妨把输入功能写成通用的方法,存放在自己的工具包中,下次使用,直接粘贴,很方面。(用我GitHub上代码时能不能点个星)

下面是python代码。完全可以不用看,直接看方法2

# https://github.com/zihaozhang9/utils/blob/master/OnlineExam.py

def decIn(Str_in):

line = Str_in.strip().split()

try:

line = [int(i) for i in line]

except:

print('input error')

exit()

return line

def read1(chang):

tmp = decIn(input())

while len(tmp)

tmp = decIn(input())

return tmp

def swap(t1, t2):

return t2, t1

#读取输入

n = read1(1)[0]

line1 = read1(1)

linesort = line1.copy()

linesort.sort()

#获取所有排列组合情况

lines = []

while True:

lines.append(linesort.copy())

j = n-2

while linesort[j]>=linesort[j+1]:

j = j-1

if j<0: break

k = n -1

while (k>j)and(linesort[k]<=linesort[j]):

k = k-1

linesort[k],linesort[j]=swap(linesort[k],linesort[j])

l = j+1

r = n-1

while l

linesort[l],linesort[r]=swap(linesort[l],linesort[r])

l = l+1

r = r-1

#计算Q

Q=0

for idx,i in enumerate(lines):

if line1 == i:

Q = idx

break

#给出倒数第Q的结果

Q=Q+1

for i in lines[-Q]:

print(i,end=' ') 结果当然是可以运行, 但时间复杂度太高,测试用例只通过40%。

方法二,五行代码 可以将所有的排列组合看成一种树结构。【第Q中排列】和【倒数第Q种】排列其实是对称的。我们不需要知道所有的排列组合情况,我们只需要根据当前顺序对称过去就好了。

代码-核心代码其实就5行。不过这是考完之后想到的,没测试过,不一定对。

def decIn(Str_in):

line = Str_in.strip().split()

try:

line = [int(i) for i in line]

except:

print('input error')

exit()

return line

def read1(chang):

tmp = decIn(input())

while len(tmp)

tmp = decIn(input())

return tmp

n = read1(1)[0]

line_in = read1(1)

linesort = line_in.copy()

linesort.sort()

#或得到对称的元素

def getflip(line,e):

idx = line.index(e)+1

return line[-idx]

#直接打印结果

for e in line_in:

print( getflip(linesort,e), end=' ')

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值