來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/next-permutation
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán)粘衬,非商業(yè)轉(zhuǎn)載請注明出處摧玫。
題目
實(shí)現(xiàn)獲取下一個(gè)排列的函數(shù),算法需要將給定數(shù)字序列重新排列成字典序中下一個(gè)更大的排列衅斩。
如果不存在下一個(gè)更大的排列盆顾,則將數(shù)字重新排列成最小的排列(即升序排列)。
必須原地修改畏梆,只允許使用額外常數(shù)空間您宪。
以下是一些例子奈懒,輸入位于左側(cè)列,其相應(yīng)輸出位于右側(cè)列宪巨。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
不明白題意磷杏,但是看解析是說。是這樣
1捏卓、先找出最大的索引 k 滿足 nums[k] < nums[k+1]极祸,如果不存在,就翻轉(zhuǎn)整個(gè)數(shù)組怠晴;
2遥金、再找出另一個(gè)最大索引 l 滿足 nums[l] > nums[k];
3龄寞、交換 nums[l] 和 nums[k]汰规;
4、最后翻轉(zhuǎn) nums[k+1:]物邑。
方法
func nextPermutation(_ nums: inout [Int]) {
if nums.count == 0 {
return
}
var firstIndex = -1
for i in stride(from: nums.count - 2, through: 0, by: -1) {
if nums[i] < nums[i+1] {
firstIndex = i
break
}
}
if firstIndex == -1 {
reverseNums(&nums, 0, nums.count - 1)
return
}
var secondIndex = -1
for i in stride(from: nums.count - 1, through: 0, by: -1) {
if nums[i] > nums[firstIndex] {
secondIndex = i
break
}
}
swapNums(&nums, firstIndex, secondIndex)
reverseNums(&nums, firstIndex + 1, nums.count - 1)
return;
}
func reverseNums(_ nums: inout [Int], _ fromIndex: Int, _ toIndex: Int) {
var fromIndex = fromIndex
var toIndex = toIndex
while fromIndex < toIndex {
swapNums(&nums, fromIndex , toIndex)
fromIndex += 1
toIndex -= 1
}
}
func swapNums(_ nums: inout [Int], _ fromIndex: Int, _ toIndex: Int) {
let tmp = nums[fromIndex];
nums[fromIndex] = nums[toIndex];
nums[toIndex] = tmp;
}
image.png