• [Swift]LeetCode31. 下一个排列 | Next Permutation


    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9897957.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

    The replacement must be in-place and use only constant extra memory.

    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1


    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

    如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

    必须原地修改,只允许使用额外常数空间。

    以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1


     【一遍扫描】算法

    首先,我们观察到对于任何给定序列的降序,没有可能的下一个更大的排列。

    例如,以下数组不可能有下一个排列:

    [9, 5, 4, 3, 1]

    我们需要从右边找到第一对两个连续的数字 a[i]a[i] 和 a[i-1]a[i1],它们满足 a[i]>a[i-1]a[i]>a[i1]。现在,没有对 a[i-1]a[i1]右侧的重新排列可以创建更大的排列,因为该子数组由数字按降序组成。因此,我们需要重新排列 a[i-1]a[i1] 右边的数字,包括它自己。

    现在,什么样的重新排列将产生下一个更大的数字?我们想要创建比当前更大的排列。因此,我们需要将数字 a[i-1]a[i1] 替换为位于其右侧区域的数字中比它更大的数字,例如 a[j]a[j]。

     Next Permutation

    我们交换数字 a[i-1]a[i1] 和 a[j]a[j]。我们现在在索引 i-1i1 处有正确的数字。 但目前的排列仍然不是我们正在寻找的排列。我们需要通过仅使用 a[i-1]a[i1]右边的数字来形成最小的排列。 因此,我们需要放置那些按升序排列的数字,以获得最小的排列。

    但是,请记住,在从右侧扫描数字时,我们只是继续递减索引直到我们找到 a[i]a[i] 和 a[i-1]a[i1] 这对数。其中,a[i] > a[i-1]a[i]>a[i1]。因此,a[i-1]a[i1] 右边的所有数字都已按降序排序。此外,交换 a[i-1]a[i1] 和 a[j]a[j] 并未改变该顺序。因此,我们只需要反转 a[i-1]a[i1] 之后的数字,以获得下一个最小的字典排列。

    下面的动画将有助于你理解:


    Next Permutation


     24ms


    1
    class Solution { 2 func nextPermutation(_ nums: inout [Int]) { 3 let len:Int = nums.count 4 var i:Int = len - 2 5 while (i >= 0 && nums[i + 1] <= nums[i]) {i -= 1} 6 if i >= 0 7 { 8 var j:Int = len - 1 9 while (j >= 0 && nums[j] <= nums[i]) {j -= 1} 10 swap(&nums, i, j) 11 } 12 reverse(&nums, i + 1) 13 } 14 15 func reverse(_ nums:inout [Int],_ start:Int) 16 { 17 var i:Int = start, j:Int = nums.count - 1 18 while (i < j) 19 { 20 swap(&nums, i, j) 21 i += 1 22 j -= 1 23 } 24 } 25 26 func swap(_ nums:inout [Int],_ i:Int,_ j:Int) 27 { 28 var temp:Int = nums[i] 29 nums[i] = nums[j] 30 nums[j] = temp 31 } 32 }

    12ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         if nums.count <= 1 { return }
     4         var ind = -1
     5         for i in (0..<(nums.count-1)).reversed() {
     6             if nums[i] < nums[i+1] {
     7                 ind = i
     8                 break
     9             }
    10         }
    11         if ind == -1 { 
    12             nums = nums.reversed() 
    13             return
    14         }
    15         let ind1 = ind
    16         var temp = nums[ind+1]
    17         var ind2 = ind+1
    18         while ind < nums.count {
    19             if nums[ind] > nums[ind1] && nums[ind] <= temp { 
    20                 ind2 = ind
    21                 temp = nums[ind]
    22             }
    23             ind += 1
    24         }
    25         (nums[ind1], nums[ind2]) = (nums[ind2], nums[ind1])
    26         nums = Array(nums[0...ind1]) + Array(nums[(ind1+1)..<nums.count]).reversed()
    27     }
    28 }

    16ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         guard let violateIndex = findViolate(nums) else {
     4             nums.reverse()
     5             return
     6         }
     7         
     8         swap(&nums, violateIndex, findLeastGreater(nums, violateIndex))
     9         nums = nums[0...violateIndex] + nums[(violateIndex + 1)...].reversed()
    10     }
    11     
    12     fileprivate func findViolate(_ nums: [Int]) -> Int? {
    13         for i in (1..<nums.count).reversed() {
    14             if nums[i] > nums[i - 1] {
    15                 return i - 1
    16             }
    17         }
    18         
    19         return nil
    20     }
    21     
    22     fileprivate func findLeastGreater(_ nums: [Int], _ violateIndex: Int) -> Int {
    23         for i in (violateIndex + 1..<nums.count).reversed() {
    24             if nums[i] > nums[violateIndex] {
    25                 return i
    26             }
    27         }
    28         
    29         fatalError()
    30     }
    31     
    32     fileprivate func swap<T>(_ nums: inout [T], _ indexL: Int, _ indexR: Int) {
    33         (nums[indexL], nums[indexR]) = (nums[indexR], nums[indexL])
    34     }
    35 }

    16ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         
     4         guard nums.count > 1 else {
     5             return
     6         }
     7         
     8         for i in (0 ..< nums.count - 1).reversed() {
     9             
    10             var lowestDiff = -1
    11             var lowestIndex = -1
    12             
    13             for j in (i+1 ..< nums.count) {
    14                
    15                 let diff = nums[j] - nums[i]
    16                 
    17                 if diff > 0 && (diff < lowestDiff || lowestDiff == -1) {
    18                     lowestDiff = diff
    19                     lowestIndex = j
    20                 }
    21             }
    22             
    23             if (lowestIndex >= 0) {
    24                 print("swap (nums[i]) (nums[lowestIndex])")
    25                 swap(&nums, i, lowestIndex)
    26                 nums[i+1..<nums.count].sort()
    27                 return
    28             }
    29         }
    30         
    31         for i in (0 ..< nums.count / 2) {
    32             swap(&nums, i, nums.count - i - 1)
    33         }
    34     }
    35     
    36     func swap(_ nums: inout [Int], _ i: Int, _ j: Int) {
    37         let tmp = nums[i]
    38         nums[i] = nums[j]
    39         nums[j] = tmp
    40     }
    41 }

    20ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         
     4         var end = nums.count - 1
     5        
     6         while end > 0 {
     7             if nums[end - 1] < nums[end] {
     8                 break
     9             }
    10             end -= 1
    11         }
    12         
    13         if end == 0 {
    14             for i in 0..<nums.count / 2 {
    15                 nums.swapAt(i, nums.count - 1 - i)
    16             }
    17         } else {
    18             end -= 1
    19             var i = nums.count - 1
    20             while i > end {
    21                 if nums[i] > nums[end] {
    22                     break
    23                 }
    24                 i -= 1
    25             }
    26             
    27             nums.swapAt(i, end)
    28             
    29             for i in 0..<(nums.count - end) / 2 {
    30                 nums.swapAt(end + 1 + i, nums.count - 1 - i)
    31             } 
    32         }
    33     }
    34 }

    20ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         
     4         let size = nums.count
     5         
     6         //数组为空或只有一个数
     7         if size == 0 || size == 1 {
     8             return
     9         }
    10         
    11         //只有两个数直接交换
    12         if size == 2 {
    13             nums.swapAt(0, 1)
    14             return
    15         }
    16         
    17         //判断大小交换位置
    18         for index in stride(from: size-1, through: 1, by: -1) {
    19             
    20             if nums[index] > nums[index - 1] {
    21                 
    22                 for subIndex in stride(from: size-1, through: index, by: -1) {
    23                     
    24                     if nums[subIndex] > nums[index-1] {
    25                         
    26                         nums.swapAt(index-1, subIndex)
    27                         break
    28                     }
    29                 }
    30                 
    31                 for tmpIndex in stride(from: (size-1-index)/2, through: 0, by: -1) {
    32                     
    33                     nums.swapAt(tmpIndex + index, size - 1 - tmpIndex)
    34                 }
    35                 
    36                 return
    37                 
    38             }
    39         }
    40         
    41         //降序排列好,直接逆序
    42         for index in stride(from: (size-1)/2, through: 0, by: -1) {
    43             
    44             nums.swapAt(index, size-1-index)
    45         }
    46     }
    47 }

    24ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         
     4         guard nums.count > 1 else {
     5             return
     6         }
     7         
     8         for i in (0 ..< nums.count - 1).reversed() {
     9             
    10             var lowestDiff = -1
    11             var lowestIndex = -1
    12             
    13             for j in (i+1 ..< nums.count) {
    14                
    15                 let diff = nums[j] - nums[i]
    16                 
    17                 if diff > 0 && (diff < lowestDiff || lowestDiff == -1) {
    18                     lowestDiff = diff
    19                     lowestIndex = j
    20                 }
    21             }
    22             
    23             if (lowestIndex >= 0) {
    24                 print("swap (nums[i]) (nums[lowestIndex])")
    25                 swap(&nums, i, lowestIndex)
    26                 nums[i+1..<nums.count].sort()
    27                 return
    28             }
    29         }
    30         
    31         for i in (0 ..< nums.count / 2) {
    32             swap(&nums, i, nums.count - i - 1)
    33         }
    34     }
    35     
    36     func swap(_ nums: inout [Int], _ i: Int, _ j: Int) {
    37         let tmp = nums[i]
    38         nums[i] = nums[j]
    39         nums[j] = tmp
    40     }
    41 }

    28ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         if nums.count < 2 {
     4             return
     5         }
     6         
     7         var max = nums[nums.count - 1]
     8         var i = nums.count - 2
     9         while i >= 0 {
    10             if nums[i] < max {
    11                 break
    12             }
    13             max = nums[i]
    14             i = i - 1
    15         }
    16         if i < 0 {
    17             nums.sort()
    18             return
    19         }
    20         var x = nums[i]
    21         nums[(i+1)...].sort()
    22         var left = i + 1
    23         var right = nums.index(before: nums.endIndex)
    24         
    25         while right > (left + 1) {
    26             var m = left + (right - left) / 2
    27             if nums[m] <= x {
    28                 left = m
    29             } else {
    30                 right = m
    31             }
    32         }
    33       
    34         var ind = (x < nums[left]) ? left : right
    35         nums[i] = nums[ind]
    36         nums[ind] = x
    37     }
    38 }

    32ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         var toSwap = -1
     4         
     5         if nums.count <= 1 {
     6             return
     7         }
     8         
     9         for index in (1...nums.count - 1).reversed() {
    10             if nums[index] > nums[index - 1] {
    11                 toSwap = index - 1
    12                 break
    13             }
    14         }
    15         
    16         if toSwap != -1 {
    17             var min = Int.max, swapIndex = toSwap
    18             for index in (toSwap + 1...nums.count - 1).reversed() {
    19                 if nums[index] < min && nums[index] > nums[toSwap] {
    20                     swapIndex = index
    21                     min = nums[index]
    22                 }
    23             }
    24             nums.swapAt(toSwap, swapIndex)
    25             nums[toSwap + 1...nums.count - 1].reverse()
    26         } else {
    27             nums.reverse()
    28         }
    29     }
    30 }

    36ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         //no arrangement possible
     4         if(nums.sorted().reversed() == nums){
     5             nums = nums.sorted()
     6             return
     7         }
     8         let n = nums.count
     9         var position = -1
    10         for i in (0 ..< n - 1).reversed() {
    11             print(i)
    12             if nums[i] < nums[i + 1] {
    13                 position = i
    14                 break
    15             }
    16         }
    17         var indexToSwap = -1
    18         var diff = Int.max
    19         
    20         
    21         for j in (position+1 ..< n).reversed() {
    22             let d =  nums[j] - nums[position]
    23                 if d < diff && d > 0 {
    24                     indexToSwap = j
    25                     diff = d
    26                 }
    27             }
    28         nums.swapAt(position, indexToSwap)
    29         nums = nums[0 ... position] + nums[position + 1 ... nums.count - 1].reversed()
    30         
    31         
    32         
    33         
    34         
    35     }
    36 }

    44ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         if nums.count < 2 {
     4             return
     5         }
     6         
     7         var max = nums[nums.count - 1]
     8         var i = nums.count - 2
     9         while i >= 0 {
    10             if nums[i] < max {
    11                 break
    12             }
    13             max = nums[i]
    14             i = i - 1
    15         }
    16         if i < 0 {
    17             nums.sort()
    18             return
    19         }
    20         var x = nums[i]
    21         nums[(i+1)...].sort()
    22         var left = i + 1
    23         var right = nums.index(before: nums.endIndex)
    24         
    25         while right > left {
    26             var m = left + (right - left) / 2
    27             if nums[m] <= x {
    28                 if nums[m+1] > x {
    29                     left = m
    30                     right = m + 1
    31                     break
    32                 }
    33                 left = m + 1
    34             } else {
    35                 if nums[m-1] <= x {
    36                     left = m - 1
    37                     right = m
    38                     break
    39                 }
    40                 right = m - 1
    41             }
    42         }
    43       
    44         nums[i] = nums[right]
    45         nums[right] = x
    46     }
    47 }

    48ms

     1 class Solution {
     2     func nextPermutation(_ nums: inout [Int]) {
     3         var left = 0
     4         var right = nums.count - 1
     5         for i in (0 ..< nums.count - 1).reversed() {
     6             if nums[i] >= nums[i + 1] {
     7                 continue
     8             } else {
     9                 left = i
    10                 break
    11             }
    12         }
    13         
    14         var nextIndex = 0
    15         for i in (0 ..< nums.count).reversed() {
    16             if nums[i] > nums[left] {
    17                 nextIndex = i 
    18                 break
    19             }
    20         }
    21 
    22         nums.swapAt(left, nextIndex)
    23         if nextIndex != 0 {
    24             left += 1
    25         }
    26         while left < right {
    27             nums.swapAt(left, right)
    28             left += 1
    29             right -= 1
    30         }
    31     }
    32 }
  • 相关阅读:
    js异步编程思想【node的精华】
    python偏函数
    软工划水日报-安卓端侧部署(1) 4/23
    软工划水日报-模型预测 4/22
    软工划水日报-《构建之法》阅读笔记SONO.5 4/21
    软工划水日报-paddle模型训练(3) 4/20
    软工划水日报-paddle模型训练(2) 4/19
    软工划水日报-paddle模型训练(1) 4/18
    软工划水日报-CUDA下载与安装 4/17
    软工划水日报-AIchallager数据集下载及处理 4/16
  • 原文地址:https://www.cnblogs.com/strengthen/p/9897957.html
Copyright © 2020-2023  润新知