日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数组的合并和升序排列_leetcode No.31 下一个排列

發(fā)布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数组的合并和升序排列_leetcode No.31 下一个排列 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:

下一個排列 - 力扣(LeetCode)?leetcode-cn.com

題目描述:

實(shí)現(xiàn)獲取下一個排列的函數(shù),算法需要將給定數(shù)字序列重新排列成字典序中下一個更大的排列。

如果不存在下一個更大的排列,則將數(shù)字重新排列成最小的排列(即升序排列)。

必須原地修改,只允許使用額外常數(shù)空間。

以下是一些例子,輸入位于左側(cè)列,其相應(yīng)輸出位于右側(cè)列。1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1

解題思路:

最直接的想法是暴力法,找出由給定數(shù)組的元素形成的列表的每個可能的排列,并找出比給定的排列更大的排列。但是時間復(fù)雜度是

,因?yàn)榭赡艿呐帕锌傆嬘? 個,爆表了都,我們得想想有沒有更快的算法。

首先,如果是一個降序數(shù)組,沒有可能有下一個更大的排列,直接反轉(zhuǎn)變成升序數(shù)組就好。

然后,我們再來看看一般情形,假設(shè)數(shù)組名為

,長度為 ,這個數(shù)組中必然存在著 ,使得 ,我們對 以及其右邊的數(shù)進(jìn)行重新排列就可以得到一個比初始排列大的排列。

而要想找到下一個排列,我們可以從右往左來找到第一對滿足

的 。接著,我們需要在 的右邊發(fā)現(xiàn)一個 ,使得 ,且 在所有大于 的值中最小,我們交換 和 的位置。

來自 leetcode 官方題解

現(xiàn)在在索引

處有正確的數(shù)字。但目前的排列仍然不是答案,我們需要通過僅使用 右邊的數(shù)字來形成最小的排列。 因此,我們需要放置那些按升序排列的數(shù)字,以獲得最小的排列。

可能你想到直接排序就好了嘛,但其實(shí)還有更簡單的方法。因?yàn)樵趶挠覀?cè)掃描數(shù)字時,我們只是持續(xù)遞減索引直到我們找到

和 這對數(shù)。其中, 。 右邊的所有數(shù)字都已按降序排序。此外,交換 和 也并未改變該順序。因此,我們只需要反轉(zhuǎn) 之后的數(shù)字,就可以獲得下一個最小的字典排列。

代碼如下:

class Solution { public:void nextPermutation(vector<int>& nums) {int n = nums.size(), k, l;for (k = n - 2; k >= 0; k--) {if (nums[k] < nums[k + 1]) {break;}}if(k < 0) {reverse(nums.begin(), nums.end());}else {for (l = n - 1; l > k; l--) {if (nums[l] > nums[k]) {break;}}swap(nums[k], nums[l]);reverse(nums.begin()+k+1, nums.end());}} };

其實(shí) C++ 里面有庫函數(shù) next_permutation 可以直接幫我們獲取下一個排列。。。

如果有任何疑問,歡迎提出。如果有更好的解法,也歡迎告知。

總結(jié)

以上是生活随笔為你收集整理的数组的合并和升序排列_leetcode No.31 下一个排列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。