Skip to content

Commit a440c74

Browse files
authored
Merge pull request soapyigu#366 from soapyigu/Array
Array
2 parents 6266047 + 220c9e0 commit a440c74

File tree

2 files changed

+77
-21
lines changed

2 files changed

+77
-21
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Question Link: https://leetcode.com/problems/next-palindrome-using-same-digits/
3+
* Primary idea: Figure out the first half's next permutation, then double it to the result.
4+
*
5+
* Time Complexity: O(n), Space Complexity: O(1)
6+
*
7+
*/
8+
9+
class NextPalindromeUsingSameDigits {
10+
func nextPalindrome(_ num: String) -> String {
11+
let num = Array(num)
12+
var firstHalf = num[0..<num.count / 2].compactMap { Int(String($0)) }
13+
14+
if num.count <= 1 || !nextPermutation(&firstHalf) {
15+
return ""
16+
}
17+
18+
let firstHalfStr = firstHalf.map { String($0) }.joined()
19+
20+
if num.count % 2 == 0 {
21+
return firstHalfStr + firstHalfStr.reversed()
22+
} else {
23+
return firstHalfStr + String(num[num.count / 2]) + firstHalfStr.reversed()
24+
}
25+
}
26+
27+
private func nextPermutation(_ nums: inout [Int]) -> Bool {
28+
var violateIdx = -1
29+
30+
for i in (1..<nums.count).reversed() {
31+
if nums[i] > nums[i - 1] {
32+
violateIdx = i - 1
33+
break
34+
}
35+
}
36+
37+
if violateIdx == -1 {
38+
nums.reverse()
39+
return false
40+
}
41+
42+
for i in ((violateIdx + 1)..<nums.count).reversed() {
43+
if nums[i] > nums[violateIdx] {
44+
swap(&nums, i, violateIdx)
45+
break
46+
}
47+
}
48+
49+
nums[(violateIdx + 1)...].reverse()
50+
return true
51+
}
52+
53+
private func swap(_ nums: inout [Int], _ l: Int, _ r: Int) {
54+
(nums[l], nums[r]) = (nums[r], nums[l])
55+
}
56+
}

Array/NextPermutation.swift

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,36 @@
99

1010
class NextPermutation {
1111
func nextPermutation(_ nums: inout [Int]) {
12-
guard let violateIndex = findViolate(nums) else {
12+
guard let violateIdx = findViolate(nums) else {
1313
nums.reverse()
1414
return
1515
}
16-
17-
swap(&nums, violateIndex, findLeastGreater(nums, violateIndex))
18-
nums = nums[0...violateIndex] + nums[(violateIndex + 1)...].reversed()
16+
17+
swap(&nums, findFirstGreater(nums, violateIdx), violateIdx)
18+
nums[(violateIdx + 1)...].reverse()
19+
}
20+
21+
private func findFirstGreater(_ nums: [Int], _ violateIdx: Int) -> Int {
22+
for i in ((violateIdx + 1)..<nums.count).reversed() {
23+
if nums[i] > nums[violateIdx] {
24+
return i
25+
}
26+
}
27+
28+
return -1
1929
}
20-
21-
fileprivate func findViolate(_ nums: [Int]) -> Int? {
30+
31+
private func findViolate(_ nums: [Int]) -> Int? {
2232
for i in (1..<nums.count).reversed() {
2333
if nums[i] > nums[i - 1] {
2434
return i - 1
2535
}
2636
}
27-
37+
2838
return nil
2939
}
30-
31-
fileprivate func findLeastGreater(_ nums: [Int], _ violateIndex: Int) -> Int {
32-
for i in (violateIndex + 1..<nums.count).reversed() {
33-
if nums[i] > nums[violateIndex] {
34-
return i
35-
}
36-
}
37-
38-
fatalError()
39-
}
40-
41-
fileprivate func swap<T>(_ nums: inout [T], _ indexL: Int, _ indexR: Int) {
42-
(nums[indexL], nums[indexR]) = (nums[indexR], nums[indexL])
40+
41+
private func swap(_ nums: inout [Int], _ l: Int, _ r: Int) {
42+
(nums[l], nums[r]) = (nums[r], nums[l])
4343
}
44-
}
44+
}

0 commit comments

Comments
 (0)