一、題目描述
給出乙個數,找出這個正整數所有數字全排列的下乙個數。
即:在乙個整數所包含數字的全部組合中,找到乙個大於且僅大於原數的新整數。
如:如果輸入12345,則返回12354;
如果輸入12354,則返回12435
二、解題思路
首先當這5個數字逆序組合時最大:54321;順序組合時最小:12345
為了得到比原數稍大的下乙個數,我們需要盡量保持高位不變,低位在最小的範圍內變換順序。
至於變換順序的範圍大小,則取決於當前整數的逆序區域。
比如:12354,要想獲得比它大的下乙個數,則需要從倒數第三位開始改變。首先從後面的逆序區域中找到大於3的最小數字,讓其和3的位置進行互換。然後,需要把最後兩位變成順序狀態,讓後兩位盡可能的小。
1、從後向前檢視逆序區域,找到逆序區域的前一位,也就是數字置換的邊界。
2、讓逆序區域的前一位和逆序區域中大於它的最小的數字交換位置。
3、讓原來的逆序區域變成順序狀態。
**實現:
def
find_nearest_number
(numbers=
):# 1、從後向前檢視逆序區域,找到逆序區域的最後一位
index=find_transfer_point(numbers)
# 如果數字置換的邊界是0,說明整個陣列已經逆序,無法得到更大的數字,返回null
if index==0:
return
none
# 2、把逆序區域的前一位和逆序區域中剛剛大於它的數字進行交換
# 複製入參,避免直接修改入參
numbers_copy=numbers.copy(
) exchange_head(index,numbers_copy)
# 3、把原來的逆序區域變為順序
reverse(index,numbers_copy)
return numbers_copy
deffind_transfer_point
(numbers=
):for i in
range
(len
(numbers)-1
,0,-
1):if numbers[i]
>numbers[i-1]
:return i
return
0def
exchange_head
(index,numbers=
):head=numbers[index-1]
for i in
range
(len
(numbers)-1
,0,-
1):# 因為後續資料是逆序的,遇到第乙個大於head的,肯定就是所有大於它的資料中最小的乙個
if head
: numbers[index-1]
=numbers[i]
numbers[i]
=head
break
return numbers
defreverse
(index,numbers=
):i=index
j=len(numbers)-1
while i
numbers[i]
,numbers[j]
=numbers[j]
,numbers[i]
i +=
1 j -=
1return numbers
defoutput_numbers
(numbers=
):for i in numbers:
print
(i,end="")
print()
my_numbers=
list([
1,2,
6,3,
5,4]
)output_numbers(find_nearest_number(my_numbers)
)
尋找全排列的下乙個數
題目 給出乙個正整數,找出這個正整數所有數字全排列的下乙個數。即就是在乙個整數包含數字的全部組合中,找到乙個大於且僅大於原數的新整數。例如 輸入12345,則返回12354。解題思路 從後向前檢視逆序區域,找到逆序區域的前一位,也就是數字交換的邊界 讓逆序區域的前一位和逆序區域中大於它的最小的數字交...
leetcode 尋找全排列的下乙個數
給定乙個正整數,實現乙個方法來求出離該整數最近的大於自身的 換位數 什麼是換位數呢?就是把乙個整數各個數字的數字進行全排列,從而得到新的整數。例如53241和23541。題目要求寫乙個方法來尋找最近的且大於自身的換位數。比如下面這樣 輸入12345,返回12354 輸入12354,返回12435 輸...
讀書筆記 漫畫演算法 6 尋找全排列的下乙個數
給出乙個數,求出由每位數形成的所有全排列中,大於此數的最小值 注 我們給出的這個數每位都不同 具體的演算法描述如下 1.從後向前尋找逆序區域,並返回逆序區域的最左側索引 2.將nums index 1 與nums區間 index,nums.length 1 中大於nums index 1 的最小元素...