数组的合并和升序排列_leetcode No.31 下一个排列
生活随笔
收集整理的這篇文章主要介紹了
数组的合并和升序排列_leetcode No.31 下一个排列
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:
下一個排列 - 力扣(LeetCode)?leetcode-cn.com題目描述:
實現獲取下一個排列的函數,算法需要將給定數字序列重新排列成字典序中下一個更大的排列。
如果不存在下一個更大的排列,則將數字重新排列成最小的排列(即升序排列)。
必須原地修改,只允許使用額外常數空間。
以下是一些例子,輸入位于左側列,其相應輸出位于右側列。1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1
解題思路:
最直接的想法是暴力法,找出由給定數組的元素形成的列表的每個可能的排列,并找出比給定的排列更大的排列。但是時間復雜度是
,因為可能的排列總計有 個,爆表了都,我們得想想有沒有更快的算法。首先,如果是一個降序數組,沒有可能有下一個更大的排列,直接反轉變成升序數組就好。
然后,我們再來看看一般情形,假設數組名為
,長度為 ,這個數組中必然存在著 ,使得 ,我們對 以及其右邊的數進行重新排列就可以得到一個比初始排列大的排列。而要想找到下一個排列,我們可以從右往左來找到第一對滿足
的 。接著,我們需要在 的右邊發現一個 ,使得 ,且 在所有大于 的值中最小,我們交換 和 的位置。來自 leetcode 官方題解現在在索引
處有正確的數字。但目前的排列仍然不是答案,我們需要通過僅使用 右邊的數字來形成最小的排列。 因此,我們需要放置那些按升序排列的數字,以獲得最小的排列。可能你想到直接排序就好了嘛,但其實還有更簡單的方法。因為在從右側掃描數字時,我們只是持續遞減索引直到我們找到
和 這對數。其中, 。 右邊的所有數字都已按降序排序。此外,交換 和 也并未改變該順序。因此,我們只需要反轉 之后的數字,就可以獲得下一個最小的字典排列。代碼如下:
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());}} };其實 C++ 里面有庫函數 next_permutation 可以直接幫我們獲取下一個排列。。。
如果有任何疑問,歡迎提出。如果有更好的解法,也歡迎告知。
總結
以上是生活随笔為你收集整理的数组的合并和升序排列_leetcode No.31 下一个排列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飞机大战(Java)
- 下一篇: java 正则表达式验证邮箱格式是否合规