Merge pull request #34 from zztian1024/main

为数组篇&链表篇&二叉树 增加 Swift 实现
pull/36/head
算法基地 2021-07-20 15:05:11 +08:00 committed by GitHub
commit 10a7420457
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1472 additions and 4 deletions

View File

@ -102,3 +102,34 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
func inorderTraversal(_ root: TreeNode?) -> [Int] {
var list:[Int] = []
guard root != nil else {
return list
}
var p1 = root, p2: TreeNode?
while p1 != nil {
p2 = p1!.left
if p2 != nil {
while p2!.right != nil && p2!.right !== p1 {
p2 = p2!.right
}
if p2!.right == nil {
p2!.right = p1
p1 = p1!.left
continue
} else {
p2!.right = nil
}
}
list.append(p1!.val)
p1 = p1!.right
}
return list
}
}
```

View File

@ -51,5 +51,32 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
func inorderTraversal(_ root: TreeNode?) -> [Int] {
var arr:[Int] = []
var cur = root
var stack:[TreeNode] = []
while !stack.isEmpty || cur != nil {
//找到当前应该遍历的那个节点
while cur != nil {
stack.append(cur!)
cur = cur!.left
}
//此时指针指向空,也就是没有左子节点,则开始执行出栈操作
if let temp = stack.popLast() {
arr.append(temp.val)
//指向右子节点
cur = temp.right
}
}
return arr
}
}
```
###

View File

@ -406,6 +406,42 @@ public:
};
```
Swift Code
```swift
class Solution {
func levelOrder(_ root: TreeNode?) -> [[Int]] {
var res:[[Int]] = []
guard root != nil else {
return res
}
var queue:[TreeNode?] = []
queue.append(root!)
while !queue.isEmpty {
let size = queue.count
var list:[Int] = []
for i in 0..<size {
guard let node = queue.removeFirst() else {
continue
}
if node.left != nil {
queue.append(node.left)
}
if node.right != nil {
queue.append(node.right);
}
list.append(node.val)
}
res.append(list)
}
return res
}
}
```
On On

View File

@ -103,4 +103,41 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
func preorderTraversal(_ root: TreeNode?) -> [Int] {
var list:[Int] = []
guard root != nil else {
return list
}
var p1 = root, p2: TreeNode?
while p1 != nil {
p2 = p1!.left
if p2 != nil {
//找到左子树的最右叶子节点
while p2!.right != nil && p2!.right !== p1 {
p2 = p2!.right
}
//添加 right 指针,对应 right 指针为 null 的情况
if p2!.right == nil {
list.append(p1!.val)
p2!.right = p1
p1 = p1!.left
continue
}
//对应 right 指针存在的情况,则去掉 right 指针
p2!.right = nil
} else {
list.append(p1!.val)
}
//移动 p1
p1 = p1!.right
}
return list
}
}
```

View File

@ -67,3 +67,32 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
func preorderTraversal(_ root: TreeNode?) -> [Int] {
var list:[Int] = []
var stack:[TreeNode] = []
guard root != nil else {
return list
}
stack.append(root!)
while !stack.isEmpty {
let temp = stack.popLast()
if let right = temp?.right {
stack.append(right)
}
if let left = temp?.left {
stack.append(left)
}
//这里也可以放到前面
list.append((temp?.val)!)
}
return list
}
}
```

View File

@ -71,6 +71,39 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
func postorderTraversal(_ root: TreeNode?) -> [Int] {
var list:[Int] = []
var stack:[TreeNode] = []
var cur = root, preNode: TreeNode?
while !stack.isEmpty || cur != nil {
//和之前写的中序一致
while cur != nil {
stack.append(cur!)
cur = cur!.left
}
//1.出栈,可以想一下,这一步的原因。
cur = stack.popLast()
//2.if 里的判断语句有什么含义?
if cur!.right === nil || cur!.right === preNode {
list.append(cur!.val)
//更新下 preNode也就是定位住上一个访问节点。
preNode = cur
cur = nil
} else {
//3.再次压入栈,和上面那条 1 的关系?
stack.append(cur!)
cur = cur!.right
}
}
return list
}
}
```
`cur = stack.pop()` `cur = stack.peek()`便
On, On

View File

@ -116,6 +116,62 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
var list:[Int] = []
func postorderTraversal(_ root: TreeNode?) -> [Int] {
guard root != nil else {
return list
}
var p1 = root, p2: TreeNode?
while p1 != nil {
p2 = p1!.left
if p2 != nil {
while p2!.right != nil && p2!.right !== p1 {
p2 = p2!.right
}
if p2!.right == nil {
p2!.right = p1
p1 = p1!.left
continue
} else {
p2!.right = nil
postMorris(p1!.left)
}
}
p1 = p1!.right
}
//以根节点为起点的链表
postMorris(root!)
return list
}
func postMorris(_ root: TreeNode?) {
let reverseNode = reverseList(root)
//从后往前遍历
var cur = reverseNode
while cur != nil {
list.append(cur!.val)
cur = cur!.right
}
reverseList(reverseNode)
}
func reverseList(_ head: TreeNode?) -> TreeNode? {
var cur = head, pre: TreeNode?
while cur != nil {
let next = cur?.right
cur?.right = pre
pre = cur
cur = next
}
return pre
}
}
```
On O1
Morris

View File

@ -200,6 +200,31 @@ class Solution {
}
```
Swift Code:
```swift
class Solution {
func countDigitOne(_ n: Int) -> Int {
var high = n, low = 0, cur = 0, count = 0, num = 1
while high != 0 || cur != 0 {
cur = high % 10
high /= 10
//这里我们可以提出 high * num 因为我们发现无论为几,都含有它
if cur == 0 {
count += high * num
} else if cur == 1 {
count += high * num + 1 + low
} else {
count += (high + 1) * num
}
low = cur * num + low
num *= 10
}
return count
}
}
```
: O(logn) O(1)

View File

@ -114,5 +114,45 @@ class Solution:
ans = max(ans, t)
return ans
```
Swift Code
```swift
class Solution {
func maxSatisfied(_ customers: [Int], _ grumpy: [Int], _ minutes: Int) -> Int {
let len = customers.count
var winSum = 0, rightSum = 0, leftSum = 0
// 右区间的值
for i in minutes..<len {
if grumpy[i] == 0 {
rightSum += customers[i]
}
}
// 窗口的值
for i in 0..<minutes {
winSum += customers[i]
}
var maxCustomer = winSum + leftSum + rightSum
// 窗口左边缘
var left = 1, right = minutes
while right < len {
// 重新计算左区间的值,也可以用 customer 值和 grumpy 值相乘获得
if grumpy[left - 1] == 0 {
leftSum += customers[left - 1]
}
// 重新计算右区间值
if grumpy[right] == 0 {
rightSum -= customers[right]
}
// 窗口值
winSum = winSum - customers[left - 1] + customers[right]
maxCustomer = max(maxCustomer, winSum + leftSum + rightSum) // 保留最大值
// 移动窗口
left += 1
right += 1
}
return maxCustomer
}
}
```

View File

@ -111,3 +111,152 @@ class Solution:
return maxwin
```
Swift Code
Swift58 / 61
```swift
class Solution {
func longestSubarray(_ nums: [Int], _ limit: Int) -> Int {
var maxQueue:[Int] = []
var minQueue:[Int] = []
let len = nums.count
var right = 0, left = 0, maxWin = 0
while right < len {
while !maxQueue.isEmpty && (maxQueue.last! < nums[right]) {
maxQueue.removeLast()
}
while !minQueue.isEmpty && (minQueue.last! > nums[right]) {
minQueue.removeLast()
}
maxQueue.append(nums[right])
minQueue.append(nums[right])
while (maxQueue.first! - minQueue.first!) > limit {
if maxQueue.first! == nums[left] {
maxQueue.removeFirst()
}
if minQueue.first! == nums[left] {
minQueue.removeFirst()
}
left += 1
}
maxWin = max(maxWin, right - left + 1)
right += 1
}
return maxWin
}
}
```
Swift使100.00%
```swift
class Solution {
func longestSubarray(_ nums: [Int], _ limit: Int) -> Int {
var maxQueue = Deque<Int>.init()
var minQueue = Deque<Int>.init()
let len = nums.count
var right = 0, left = 0, maxWin = 0
while right < len {
while !maxQueue.isEmpty && (maxQueue.peekBack()! < nums[right]) {
maxQueue.dequeueBack()
}
while !minQueue.isEmpty && (minQueue.peekBack()! > nums[right]) {
minQueue.dequeueBack()
}
maxQueue.enqueue(nums[right])
minQueue.enqueue(nums[right])
while (maxQueue.peekFront()! - minQueue.peekFront()!) > limit {
if maxQueue.peekFront()! == nums[left] {
maxQueue.dequeue()
}
if minQueue.peekFront()! == nums[left] {
minQueue.dequeue()
}
left += 1
}
maxWin = max(maxWin, right - left + 1)
right += 1
}
return maxWin
}
// 双端队列数据结构
public struct Deque<T> {
private var array: [T?]
private var head: Int
private var capacity: Int
private let originalCapacity: Int
public init(_ capacity: Int = 10) {
self.capacity = max(capacity, 1)
originalCapacity = self.capacity
array = [T?](repeating: nil, count: capacity)
head = capacity
}
public var isEmpty: Bool {
return count == 0
}
public var count: Int {
return array.count - head
}
public mutating func enqueue(_ element: T) {
array.append(element)
}
public mutating func enqueueFront(_ element: T) {
if head == 0 {
capacity *= 2
let emptySpace = [T?](repeating: nil, count: capacity)
array.insert(contentsOf: emptySpace, at: 0)
head = capacity
}
head -= 1
array[head] = element
}
public mutating func dequeue() -> T? {
guard head < array.count, let element = array[head] else { return nil }
array[head] = nil
head += 1
if capacity >= originalCapacity && head >= capacity*2 {
let amountToRemove = capacity + capacity/2
array.removeFirst(amountToRemove)
head -= amountToRemove
capacity /= 2
}
return element
}
public mutating func dequeueBack() -> T? {
if isEmpty {
return nil
} else {
return array.removeLast()
}
}
public func peekFront() -> T? {
if isEmpty {
return nil
} else {
return array[head]
}
}
public func peekBack() -> T? {
if isEmpty {
return nil
} else {
return array.last!
}
}
}
}
```

View File

@ -76,6 +76,32 @@ class Solution:
return rearr
```
Swift Code:
```swift
class Solution {
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
let count = nums.count
if count < 2 {
return [0]
}
var rearr: [Int] = []
// 查询元素
for i in 0..<count {
for j in i+1..<count {
// 发现符合条件情况
if nums[i] + nums[j] == target {
rearr.append(i)
rearr.append(j)
}
}
}
return rearr
}
}
```
****
****
@ -159,3 +185,20 @@ class Solution:
return [0]
```
Swift Code:
```swift
class Solution {
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var m:[Int:Int] = [:]
for i in 0..<nums.count {
let n = nums[i]
if let k = m[target - n] { // 如果存在则返回
return [k, i]
}
m[n] = i // 不存在则存入
}
return [0]
}
}
```

View File

@ -94,6 +94,32 @@ public:
};
```
Swift Code
```swift
class Solution {
func containsNearbyDuplicate(_ nums: [Int], _ k: Int) -> Bool {
if nums.count == 0 {
return false
}
var dict:[Int:Int] = [:]
for i in 0..<nums.count {
// 如果含有
if let v = dict[nums[i]] {
// 判断是否小于K如果小于等于则直接返回
let abs = abs(i - v)
if abs <= k {
return true
}
}
// 更新索引,此时有两种情况,不存在,或者存在时,将后出现的索引保存
dict[nums[i]] = i
}
return false
}
}
```
**HashSet**
****
@ -174,3 +200,27 @@ public:
};
```
Swift Code
```swift
class Solution {
func containsNearbyDuplicate(_ nums: [Int], _ k: Int) -> Bool {
if nums.count == 0 {
return false
}
var set:Set<Int> = []
for i in 0..<nums.count {
// 含有该元素返回true
if set.contains(nums[i]) {
return true
}
// 添加新元素
set.insert(nums[i])
if set.count > k {
set.remove(nums[i - k])
}
}
return false
}
}
```

View File

@ -164,3 +164,23 @@ public:
};
```
Swift Code
```swift
class Solution {
func removeElement(_ nums: inout [Int], _ val: Int) -> Int {
if nums.count == 0 {
return 0
}
var i = 0
for j in 0..<nums.count {
if nums[j] != val {
nums[i] = nums[j]
i += 1
}
}
return i
}
}
```

View File

@ -89,6 +89,33 @@ class Solution:
return len(res)
```
Swift Code
```swift
class Solution {
func firstMissingPositive(_ nums: [Int]) -> Int {
if nums.count == 0 {
return 1
}
// 因为是返回第一个正整数,不包括 0所以需要长度加1细节1
var res:[Int] = Array.init(repeating: 0, count: nums.count + 1)
// 将数组元素添加到辅助数组中
for x in nums {
if x > 0 && x < res.count {
res[x] = x
}
}
// 遍历查找,发现不一样时直接返回
for i in 1..<res.count {
if res[i] != i {
return i
}
}
// 缺少最后一个,例如 123此时缺少 4 细节2
return res.count
}
}
```
使使 nums 使
@ -166,3 +193,42 @@ class Solution:
return n + 1
```
Swift Code
```swift
class Solution {
func firstMissingPositive(_ nums: [Int]) -> Int {
var nums = nums
let len = nums.count
if len == 0 {
return 1
}
// 遍历数组
for i in 0..<len {
// 需要考虑指针移动情况大于0小于len+1不等与i+1
// 两个交换的数相等时,防止死循环
while nums[i] > 0
&& nums[i] < len + 1
&& nums[i] != i + 1
&& nums[i] != nums[nums[i] - 1]
{
//nums.swapAt(i, (nums[i] - 1)) // 系统方法
self.swap(&nums, i, (nums[i] - 1)) // 自定义方法
}
}
// 遍历寻找缺失的正整数
for i in 0..<len {
if nums[i] != i + 1 {
return i + 1
}
}
return len + 1
}
func swap(_ nums: inout [Int], _ i: Int, _ j: Int) {
let temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
}
}
```

View File

@ -84,6 +84,32 @@ class Solution:
return max(maxcount, right - left)
```
Swift Code
```swift
class Solution {
func findMaxConsecutiveOnes(_ nums: [Int]) -> Int {
var left = 0, right = 0, res = 0
let len = nums.count
while right < len {
if nums[right] == 1 {
right += 1
continue
}
// 保存最大值
res = max(res, right - left)
// 跳过 0 的情况
while right < len && nums[right] == 0 {
right += 1
}
// 同一起点继续遍历
left = right
}
return max(res, right - left)
}
}
```
@ -132,3 +158,22 @@ class Solution:
return ans
```
Swift Code
```swift
class Solution {
func findMaxConsecutiveOnes(_ nums: [Int]) -> Int {
let len = nums.count
var maxCount = 0, count = 0
for i in 0..<len {
if nums[i] == 1 {
count += 1
} else { // 这里可以改成 while
maxCount = max(maxCount, count)
count = 0
}
}
return max(maxCount, count)
}
}
```

View File

@ -156,5 +156,40 @@ class Solution:
return arr
```
Swift Code
```swift
class Solution {
func spiralOrder(_ matrix: [[Int]]) -> [Int] {
var arr:[Int] = []
var left = 0, right = matrix[0].count - 1
var top = 0, down = matrix.count - 1
while (true) {
for i in left...right {
arr.append(matrix[top][i])
}
top += 1
if top > down { break }
for i in top...down {
arr.append(matrix[i][right])
}
right -= 1
if left > right { break}
for i in stride(from: right, through: left, by: -1) {
arr.append(matrix[down][i])
}
down -= 1
if top > down { break}
for i in stride(from: down, through: top, by: -1) {
arr.append(matrix[i][left])
}
left += 1
if left > right { break}
}
return arr
}
}
```

View File

@ -45,6 +45,8 @@ class Solution {
Python3
Swift
使西
![](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/微信截图_20210113193831.4wk2b9zc8vm0.png)
@ -160,3 +162,27 @@ class Solution {
}
```
Swift Code
```swift
class Solution {
func subarraySum(_ nums: [Int], _ k: Int) -> Int {
if nums.count == 0 {
return 0
}
var map: [Int: Int] = [:]
map[0] = 1 // 需要添加入一个元素垫底,已支持前几位就满足的情况
var presum = 0, count = 0
for x in nums {
presum += x
//当前前缀和已知,判断是否含有 presum - k的前缀和那么我们就知道某一区间的和为 k 了。
if let v = map[presum - k] {
count += v //获取presum-k前缀和出现次数
}
map[presum] = (map[presum] ?? 0) + 1
}
return count
}
}
```

View File

@ -176,6 +176,43 @@ public:
};
```
Swift Code:
```swift
class Solution {
func spiralOrder(_ matrix: [[Int]]) -> [Int] {
var arr:[Int] = []
var left = 0, right = matrix[0].count - 1
var top = 0, down = matrix.count - 1
while (true) {
for i in left...right {
arr.append(matrix[top][i])
}
top += 1
if top > down { break }
for i in top...down {
arr.append(matrix[i][right])
}
right -= 1
if left > right { break}
for i in stride(from: right, through: left, by: -1) {
arr.append(matrix[down][i])
}
down -= 1
if top > down { break}
for i in stride(from: down, through: top, by: -1) {
arr.append(matrix[i][left])
}
left += 1
if left > right { break}
}
return arr
}
}
```
54 ,
Java Code:
@ -298,3 +335,44 @@ public:
};
```
Swift Code:
```swift
class Solution {
func generateMatrix(_ n: Int) -> [[Int]] {
var arr:[[Int]] = Array.init(repeating: Array.init(repeating: 0, count: n), count: n)
var left = 0, right = n - 1
var top = 0, bottom = n - 1
var num = 1, numSize = n * n
while true {
for i in left...right {
arr[top][i] = num
num += 1
}
top += 1
if num > numSize { break}
for i in top...bottom {
arr[i][right] = num
num += 1
}
right -= 1
if num > numSize { break}
for i in stride(from: right, through: left, by: -1) {
arr[bottom][i] = num
num += 1
}
bottom -= 1
if num > numSize { break}
for i in stride(from: bottom, through: top, by: -1) {
arr[i][left] = num
num += 1
}
left += 1
if num > numSize { break}
}
return arr
}
}
```

View File

@ -103,3 +103,23 @@ public:
};
```
Swift Code:
```swift
class Solution {
func plusOne(_ digits: [Int]) -> [Int] {
let count = digits.count
var digits = digits
for i in stride(from: count - 1, through: 0, by: -1) {
digits[i] = (digits[i] + 1) % 10
if digits[i] != 0 {
return digits
}
}
var arr: [Int] = Array.init(repeating: 0, count: count + 1)
arr[0] = 1
return arr
}
}
```

View File

@ -117,6 +117,38 @@ public:
};
```
Swift Code:
```swift
class Solution {
func sortColors(_ nums: inout [Int]) {
let count = nums.count
var left = 0, i = left, right = count - 1
while i <= right {
if nums[i] == 2 {
//nums.swapAt(i, right) 直接调用系统方法
self.swap(&nums, i, right) // 保持风格统一走自定义交换
right -= 1
} else if nums[i] == 0 {
//nums.swapAt(i, left) 直接调用系统方法
self.swap(&nums, i, left) // 保持风格统一走自定义交换
i += 1
left += 1
} else {
i += 1
}
}
}
func swap(_ nums: inout [Int], _ i: Int, _ j: Int) {
let temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
}
}
```
使
[0,0,0,1,1,1,2,2,2]
@ -220,3 +252,37 @@ public:
};
```
Swift Code:
```swift
class Solution {
func sortColors(_ nums: inout [Int]) {
let count = nums.count
var left = 0, i = left, right = count - 1
while i <= right {
if nums[i] == 0 {
//nums.swapAt(i, left) 直接调用系统方法
self.swap(&nums, i, left) // 保持风格统一走自定义交换
left += 1
}
if nums[i] == 2 {
//nums.swapAt(i, right) 直接调用系统方法
self.swap(&nums, i, right) // 保持风格统一走自定义交换
right -= 1
//如果不等于 1 则需要继续判断,所以不移动 i 指针i--
if nums[i] != 1 {
i -= 1
}
}
i += 1
}
}
func swap(_ nums: inout [Int], _ i: Int, _ j: Int) {
let temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
}
}
```

View File

@ -61,6 +61,24 @@ class Solution:
return -1
```
Swift Code:
```swift
class Solution {
func findRepeatNumber(_ nums: [Int]) -> Int {
var set: Set<Int> = []
for n in nums {
if set.contains(n) { // 如果发现某元素存在,则返回
return n
}
set.insert(n) // 存入集合
}
return -1
}
}
```
#### ****
****
@ -136,3 +154,26 @@ class Solution:
nums[temp] = temp
return -1
```
Swift Code:
```swift
class Solution {
func findRepeatNumber(_ nums: [Int]) -> Int {
if nums.isEmpty {
return -1
}
var nums = nums;
for i in 0..<nums.count {
while nums[i] != i {
if nums[i] == nums[nums[i]] {
return nums[i]
}
nums.swapAt(i, nums[i])
}
}
return -1
}
}
```

View File

@ -106,3 +106,22 @@ class Solution:
return windowlen
```
Swift Code
```swift
class Solution {
func minSubArrayLen(_ target: Int, _ nums: [Int]) -> Int {
var sum = 0, windowlen = Int.max, i = 0
for j in 0..<nums.count {
sum += nums[j]
while sum >= target {
windowlen = min(windowlen, j - i + 1)
sum -= nums[i]
i += 1
}
}
return windowlen == Int.max ? 0 : windowlen
}
}
```

View File

@ -145,6 +145,35 @@ class Solution:
return True
```
Swift Code
```swift
class Solution {
func isPalindrome(_ head: ListNode?) -> Bool {
// 这里需要用动态数组,因为我们不知道链表的长度
var arr:[Int?] = []
var copynode = head
// 将链表的值复制到数组中
while copynode != nil {
arr.append(copynode?.val)
copynode = copynode?.next
}
// 双指针遍历数组
var back = 0, pro = arr.count - 1
while back < pro {
// 判断两个指针的值是否相等
if arr[pro] != arr[back] {
return false
}
// 移动指针
back += 1
pro -= 1
}
return true
}
}
```
****
@ -375,3 +404,57 @@ class Solution:
return low
```
Swift Code
```swift
class Solution {
func isPalindrome(_ head: ListNode?) -> Bool {
if head == nil || head?.next == nil {
return true
}
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
var midnode = searchmidnode(head)
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
//这里我们用的是midnode.next需要注意因为我们找到的是中点但是我们翻转的是后半部分
var backhalf = reverse(midnode?.next);
//遍历两部分链表,判断值是否相等
var p1 = head
var p2 = backhalf
while p2 != nil {
if p1?.val != p2?.val {
midnode?.next = reverse(backhalf)
return false
}
p1 = p1?.next
p2 = p2?.next
}
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条。
midnode?.next = reverse(backhalf)
return true
}
//找到中点
func searchmidnode(_ head: ListNode?) -> ListNode? {
var fast = head, slow = head
while fast?.next != nil && fast?.next?.next != nil {
fast = fast?.next?.next
slow = slow?.next
}
return slow
}
//翻转链表
func reverse(_ slow: ListNode?) -> ListNode? {
var slow = slow
var low: ListNode?
var temp: ListNode?
while slow != nil {
temp = slow?.next
slow?.next = low
low = slow
slow = temp
}
return low
}
}
```

View File

@ -108,3 +108,20 @@ class Solution:
return False
```
Swift Code
```swift
class Solution {
func hasCycle(_ head: ListNode?) -> Bool {
var fast = head, slow = head
while fast != nil && fast?.next != nil {
fast = fast?.next?.next
slow = slow?.next
if fast === slow {
return true
}
}
return false
}
}
```

View File

@ -132,8 +132,6 @@ class Solution:
return head
```
###
@ -275,3 +273,29 @@ class Solution:
return slow
```
Swift Code
```swift
class Solution {
func detectCycle(_ head: ListNode?) -> ListNode? {
// 快慢指针
var fast = head, slow = head
while fast != nil && fast?.next != nil {
fast = fast?.next?.next
slow = slow?.next
// 相遇
if fast === slow {
// 设置一个新的指针从头节点出发慢指针速度为1所以可以使用慢指针从相遇点出发
// 此处也可以不创新结点,直接将 fast = head
var newNode = head
while newNode !== slow {
slow = slow?.next
newNode = newNode?.next
}
return slow
}
}
return nil
}
}
```

View File

@ -225,5 +225,41 @@ class Solution:
return dummyNode.next
```
Swift Code
```swift
class Solution {
func insertionSortList(_ head: ListNode?) -> ListNode? {
if head == nil && head?.next == nil {
return head
}
//哑节点
var dummyNode = ListNode(-1)
dummyNode.next = head
//pre负责指向新元素last 负责指向新元素的前一元素
//判断是否需要执行插入操作
var pre = head?.next
var last = head
while pre != nil {
//不需要插入到合适位置,则继续往下移动
if last!.val <= pre!.val {
pre = pre?.next
last = last?.next
continue
}
//开始出发,查找新元素的合适位置
var temphead = dummyNode
while temphead.next!.val <= pre!.val {
temphead = temphead.next!
}
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
last?.next = pre?.next
pre?.next = temphead.next
temphead.next = pre
//继续往下移动
pre = last?.next
}
return dummyNode.next
}
}
```

View File

@ -138,6 +138,32 @@ class Solution:
return low
```
Swift Code:
```swift
class Solution {
func reverseList(_ head: ListNode?) -> ListNode? {
// 边界条件
if head == nil || head?.next == nil {
return head
}
var pro = head
var low: ListNode?
while pro != nil {
// 代表橙色指针
var temp = pro
// 移动绿色指针
pro = pro?.next
// 反转节点
temp?.next = low
// 移动黄色指针
low = temp
}
return low
}
}
```
@ -227,6 +253,25 @@ class Solution:
return pro
```
Swift Code:
```swift
class Solution {
func reverseList(_ head: ListNode?) -> ListNode? {
// 结束条件
if head == nil || head?.next == nil {
return head
}
var pro = reverseList(head?.next)
// 将节点进行反转
head?.next?.next = head
// 防止循环
head?.next = nil
return pro
}
}
```
<br/>
> [@jaredliw](https://github.com/jaredliw)注:

View File

@ -128,3 +128,27 @@ class Solution:
return head
```
Swift Code
```swift
class Solution {
func oddEvenList(_ head: ListNode?) -> ListNode? {
if head == nil || head?.next == nil {
return head
}
var odd = head
var even = head?.next
var evenHead = even
while odd?.next != nil && even?.next != nil {
//将偶数位合在一起,奇数位合在一起
odd?.next = even?.next
odd = odd?.next
even?.next = odd?.next
even = even?.next
}
//链接
odd?.next = evenHead
return head
}
}
```

View File

@ -165,3 +165,34 @@ class Solution:
return dummy.next # headhead
```
Swift Code
```swift
class Solution {
func deleteDuplicates(_ head: ListNode?) -> ListNode? {
// 侦察兵指针
var pre = head
// 创建哑节点接上head
var dummy = ListNode(-1)
dummy.next = head
// 跟随的指针
var low:ListNode? = dummy
while pre != nil && pre?.next != nil {
if pre?.val == pre?.next?.val {
// 移动侦察兵指针直到找到与上一个不相同的元素
while pre != nil && pre?.next != nil && pre?.val == pre?.next?.val {
pre = pre?.next
}
// while循环后pre停留在最后一个重复的节点上
pre = pre?.next
// 连上新节点
low?.next = pre
} else {
pre = pre?.next
low = low?.next
}
}
return dummy.next // 注意这里传回的不是head而是虚拟节点的下一个节点head有可能已经换了
}
}
```

View File

@ -157,3 +157,34 @@ class Solution:
return headsmall.next
```
Swift Code
```swift
class Solution {
func partition(_ head: ListNode?, _ x: Int) -> ListNode? {
var pro = head
var big = ListNode(-1)
var small = ListNode(-1)
var headbig = big
var headsmall = small
//分
while pro != nil {
//大于时,放到 big 链表上
if pro!.val >= x {
big.next = pro
big = big.next!
//小于时,放到 small 链表上
} else {
small.next = pro
small = small.next!
}
pro = pro?.next
}
//细节
big.next = nil
//合
small.next = headbig.next
return headsmall.next
}
}
```

View File

@ -218,3 +218,50 @@ class Solution:
return low
```
Swift Code
```swift
class Solution {
func reverseBetween(_ head: ListNode?, _ left: Int, _ right: Int) -> ListNode? {
// 虚拟头结点
var temp = ListNode(-1)
temp.next = head
var pro:ListNode? = temp
// 来到 left 节点前的一个节点
var i = 0
for n in i..<left - 1 {
pro = pro?.next
i += 1
}
// 保存 left 节点前的一个节点
var leftNode = pro
// 来到 right 节点
for n in i..<right {
pro = pro?.next
}
// 保存 right 节点后的一个节点
var rightNode:ListNode? = pro?.next
// 切断链表
pro?.next = nil // 切断 right 后的部分
var newHead:ListNode? = leftNode?.next // 保存 left 节点
leftNode?.next = nil // 切断 left 前的部分
// 反转
leftNode?.next = reverse(newHead)
// 重新接头
newHead?.next = rightNode
return temp.next
}
// 和反转链表1代码一致
func reverse(_ head: ListNode?) -> ListNode? {
var low:ListNode?
var pro = head
while pro != nil {
var temp = pro
pro = pro?.next
temp?.next = low
low = temp
}
return low
}
}
```

View File

@ -123,3 +123,27 @@ class Solution:
return headtemp.next
```
Swift Code
```swift
class Solution {
func mergeTwoLists(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
var l1 = l1, l2 = l2
var headpro: ListNode? = ListNode(-1)
var headtemp = headpro
while l1 != nil && l2 != nil {
//接上大的那个
if l1!.val >= l2!.val {
headpro?.next = l2
l2 = l2!.next
} else {
headpro?.next = l1
l1 = l1!.next
}
headpro = headpro?.next
}
headpro?.next = l1 != nil ? l1 : l2
return headtemp?.next
}
}
```

View File

@ -135,6 +135,40 @@ class Solution:
return tempb
```
Swift Code
```swift
class Solution {
func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? {
var tempa = headA
var tempb = headB
var arr:Set<ListNode> = []
//遍历链表A将所有值都存到arr中
while tempa != nil {
arr.insert(tempa!)
tempa = tempa?.next
}
//遍历列表B如果发现某个结点已在arr中则直接返回该节点
while tempb != nil {
if arr.contains(tempb!) {
return tempb
}
tempb = tempb?.next
}
//若上方没有返回此刻tempb为null
return tempb
}
}
extension ListNode: Hashable, Equatable {
public func hash(into hasher: inout Hasher) {
hasher.combine(val)
hasher.combine(ObjectIdentifier(self))
}
public static func ==(lhs: ListNode, rhs: ListNode) -> Bool {
return lhs === rhs
}
}
```
@ -221,6 +255,25 @@ class Solution:
return tempa # tempb
```
Swift Code
```swift
class Solution {
func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? {
//定义两个节点
var tempa = headA
var tempb = headB
//循环
while tempa != tempb {
// 如果不为空就指针下移,为空就跳到另一链表的头部
tempa = tempa != nil ? tempa?.next : headB
tempb = tempb != nil ? tempb?.next : headA
}
return tempa //返回tempb也行
}
}
```
<br/>

View File

@ -136,3 +136,28 @@ class Solution:
return after
```
Swift Code
```swift
class Solution {
func getKthFromEnd(_ head: ListNode?, _ k: Int) -> ListNode? {
//特殊情况
if head == nil {
return head
}
//初始化两个指针
var pro = head, after = head
//先移动绿指针到指定位置
for i in 0..<k-1 {
pro = pro?.next
}
//两个指针同时移动
while pro?.next != nil {
pro = pro?.next
after = after?.next
}
//返回倒数第k个节点
return after
}
}
```

View File

@ -118,3 +118,20 @@ class Solution:
return slow
```
Swift Code
```swift
class Solution {
func middleNode(_ head: ListNode?) -> ListNode? {
var fast = head //快指针
var slow = head //慢指针
//循环条件,思考一下跳出循环的情况
while fast != nil && fast?.next != nil {
fast = fast?.next?.next
slow = slow?.next
}
//返回slow指针指向的节点
return slow
}
}
```

View File

@ -230,3 +230,42 @@ class Solution:
return nList.next #
```
Swift Code
```swift
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
var l1 = l1, l2 = l2
var nList = ListNode(-1) // 哑节点
var tempnode = nList
// 用来保存进位值初始化为0
var summod = 0
while l1 != nil || l2 != nil {
// 链表的节点值
let l1num = l1?.val ?? 0
let l2num = l2?.val ?? 0
// 将链表的值和进位值相加,得到为返回链表的值
var sum = l1num + l2num + summod
// 更新进位值例18/10=19/10=0
summod = sum / 10
// 新节点保存的值18%8=2则添加2
sum = sum % 10
// 添加节点
tempnode.next = ListNode(sum)
// 移动指针
tempnode = tempnode.next!
if l1 != nil {
l1 = l1?.next
}
if l2 != nil {
l2 = l2?.next
}
}
// 最后根据进位值判断需不需要继续添加节点
if (summod != 0) {
tempnode.next = ListNode(summod)
}
return nList.next //去除哑节点
}
}
```