[LeetCode] 31. 下一個排列
阿新 • • 發佈:2019-05-04
下一個 img dia 另一個 ems 交換 個數 per png
題目鏈接 : https://leetcode-cn.com/problems/next-permutation/
題目描述:
實現獲取下一個排列的函數,算法需要將給定數字序列重新排列成字典序中下一個更大的排列。
如果不存在下一個更大的排列,則將數字重新排列成最小的排列(即升序排列)。
必須原地修改,只允許使用額外常數空間。
示例:
以下是一些例子,輸入位於左側列,其相應輸出位於右側列。
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
思路:
這道題是根據維基百科 ,下圖所示:
翻譯過來:
- 先找出最大的索引
k
滿足nums[k] < nums[k+1]
,如果不存在,就翻轉整個數組; - 再找出另一個最大索引
l
滿足nums[l] > nums[k]
; - 交換
nums[l]
和nums[k]
; - 最後翻轉
nums[k+1:]
舉個例子:
比如nums = [1,2,7,4,3,1]
,下一個排列是什麽?
我們找到第一個最大索引是nums[1] = 2
再找到第二個最大索引是nums[5] = 3
交換,nums = [1,3,7,4,2,1]
;
翻轉,nums = [1,3,1,2,4,7]
完畢!
所以,
時間復雜度:\(O(n)\)
空間復雜度:\(O(1)\)
關註我的知乎專欄,了解更多解題技巧,大家共同進步!
代碼:
python
class Solution: def nextPermutation(self, nums: List[int]) -> None: """ Do not return anything, modify nums in-place instead. """ firstIndex = -1 n = len(nums) def reverse(nums, i, j): while i < j: nums[i],nums[j] = nums[j], nums[i] i += 1 j -= 1 for i in range(n-2, -1, -1): if nums[i] < nums[i+1]: firstIndex = i break #print(firstIndex) if firstIndex == -1: reverse(nums, 0, n-1) return secondIndex = -1 for i in range(n-1, firstIndex, -1): if nums[i] > nums[firstIndex]: secondIndex = i break nums[firstIndex],nums[secondIndex] = nums[secondIndex], nums[firstIndex] reverse(nums, firstIndex+1, n-1)
java
class Solution { public void nextPermutation(int[] nums) { if (nums == null || nums.length == 0) return; int firstIndex = -1; for (int i = nums.length - 2; i >= 0; i--) { if (nums[i] < nums[i + 1]) { firstIndex = i; break; } } if (firstIndex == -1) { reverse(nums, 0, nums.length - 1); return; } int secondIndex = -1; for (int i = nums.length - 1; i >= 0; i--) { if (nums[i] > nums[firstIndex]) { secondIndex = i; break; } } swap(nums, firstIndex, secondIndex); reverse(nums, firstIndex + 1, nums.length - 1); return; } private void reverse(int[] nums, int i, int j) { while (i < j) { swap(nums, i++, j--); } } private void swap(int[] nums, int i, int i1) { int tmp = nums[i]; nums[i] = nums[i1]; nums[i1] = tmp; } }
[LeetCode] 31. 下一個排列