思維開發題 下乙個排序

2021-09-03 01:23:12 字數 1289 閱讀 4041

最近從《程式設計謎題》上面看到一道很有意思的題目,這裡摘錄一下大意:

題目概述:

有n組資料,每組資料給出m和m個數(每個數之間用空格隔開),這m個數組成乙個m位數,請你求出下乙個比當前m位數大的排列組成的m位數

若是沒有,請輸出-1

輸入樣例:24

1 2 3 4

33 2 1

輸出樣例:

1243

-1還是那句話:看到這裡請自行思考10分鐘左右。

解法1.暴力

思路:求出這m個數的全排列,然後找到給定的資料,下乙個就是答案了

這裡設定乙個標記變數flag,如果都沒有找到就輸出-1。

時間複雜度:省去常數複雜度 o(n!)

**這裡就不貼了,想寫的童鞋可以自己練練手

好像還可以有乙個遞迴檢索法(我自己發明的【笑】)

就是對於每一位數都可以通過遞迴找到全排列中的位置

2.「數學解法」

這裡還是乙個所謂的數學解法

這裡比較玄學,我盡量講明白吧。

先來看解題步驟,最後再解釋:

拿序列3 4 2 1舉例子

1.從右往左找到第乙個反遞增的數a,將這個數所在的位置(下標)記為pos

在這個例子裡頭,a=3,pos=1

2.從右到左找到比a大的第乙個數b

在這裡,b=4

3.交換a和b

例子中的序列就變成了:4 3 2 1

4.將pos右邊的所有數都翻轉(最後一位變為第一位,倒數第二位變為第二位……)

例子中的序列就變成了4 1 2 3

此時的序列就是所求的解

怎麼樣,玄學吧【笑】

看到這裡,還是請自行思考5~10分鐘

一步一步理解(也可以畫圖,也可以論證,理解就行)

我的理解

我理解了蠻久,大概也是10min這樣才看懂。

第一步,找到a和pos

我們反過來理解,a是右到左反遞增數,那麼說,從右到左在pos之前的一直都是保持遞增的序列

ps:如果沒找到就直接輸出-1,自己想想為什麼

第二步,找到b

這一步還是要連著第三步一起講

第三步:交換a和b

這一步就是使新得到的序列比原序列大,連第二步來說,就是讓新的到的序列在其他比原序列大的序列中盡可能小,因為b是第乙個比a大的數

第四步:pos後面的翻轉

因為pos後的都是遞增,翻轉後就也是遞增,不過方向不一樣,翻轉後的遞增是使b為關鍵的序列最小

我盡力解釋清楚了

如果不相信諸位可以自己再試試

**太簡單也不貼了

演算法題 下乙個排列

實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。以下是一些例子,輸入位於左側列,其相應輸出位於右側列。1,2,3 1,3,2 3,2,1 1,2,3 1...

leetcode第31題下乙個排列

實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。以下是一些例子,輸入位於左側列,其相應輸出位於右側列。1,2,3 1,3,2 3,2,1 1,2,3 1...

leetcode 第31題 下乙個排列

實現獲取 下乙個排列 的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須 原地 修改,只允許使用額外常數空間。示例 1 輸入 nums 1,2,3 輸出 1,3,2 示例 2 輸入 nums 3,2,1 輸...