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)<chang:
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<r:
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)<chang:
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=' ')