题目1:24.两两交换链表中的节点
一定要画图,然后看图写代码。 否则下面那堆next 你一定会晕。
// @lc code=start
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init() { self.val = 0; self.next = nil; }
* public init(_ val: Int) { self.val = val; self.next = nil; }
* public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
* }
*/
class Solution {
func swapPairs(_ head: ListNode?) -> ListNode? {
let dummyNode = ListNode(0, head)
var curNode: ListNode? = dummyNode
while curNode?.next != nil, curNode?.next?.next != nil {
let temp1 = curNode?.next
let temp2 = curNode?.next?.next?.next
curNode?.next = curNode?.next?.next
curNode?.next?.next = temp1
temp1?.next = temp2
curNode = curNode?.next?.next
}
return dummyNode.next
}
}
// @lc code=end
题目2: 19.删除链表的倒数第N个节点
思考: 双指针还比较容易想到这种解法, 但是边界,也就是找被删除节点的上一个节点, 需要认真校对一下。
我用这个判断 while fast?.next != nil 让fast少走了一步
以至于最终slow可以定位在被删除节点的上一个节点。
// @lc code=start
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init() { self.val = 0; self.next = nil; }
* public init(_ val: Int) { self.val = val; self.next = nil; }
* public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
* }
*/
class Solution {
func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
let dummyNode: ListNode? = ListNode(0, head)
var fast = dummyNode
var slow = dummyNode
for _ in 0..<n {
fast = fast?.next
}
if fast == nil {
return dummyNode?.next
}
while fast?.next != nil {
fast = fast?.next
slow = slow?.next
}
slow?.next = slow?.next?.next
return dummyNode?.next
}
}
// @lc code=end
题目3: 160.链表相交
对齐节点后开始遍历。 一开始没想出来,思路还是要多再回忆几次。 这里可以提一下swift版本题解
// @lc code=start
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init(_ val: Int) {
* self.val = val
* self.next = nil
* }
* }
*/
class Solution {
func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? {
var lenA = 0
var lenB = 0
// 定义较长链表 和 较短链表
var longNode = headA
var shortNode = headB
while longNode != nil {
longNode = longNode?.next
lenA += 1
}
while shortNode != nil {
shortNode = shortNode?.next
lenB += 1
}
var gap = abs(lenA - lenB)
// 确保longNode 指向较长的链表
if lenB > lenA {
longNode = headB
shortNode = headA
} else {
longNode = headA
shortNode = headB
}
while gap > 0 {
gap -= 1
longNode = longNode?.next
}
while longNode != nil {
if longNode === shortNode {
return longNode
}
longNode = longNode?.next
shortNode = shortNode?.next
}
return nil
}
}
// @lc code=end
题目4: 142.环形链表II
过程的确有很多证明需要理解, 可以先记下来了。
class Solution {
func detectCycle(_ head: ListNode?) -> ListNode? {
var slow: ListNode? = head
var fast: ListNode? = head
while fast != nil && fast?.next != nil {
slow = slow?.next
fast = fast?.next?.next
if slow === fast {
// 环内相遇
var list1: ListNode? = slow
var list2: ListNode? = head
while list1 !== list2 {
list1 = list1?.next
list2 = list2?.next
}
return list2
}
}
return nil
}
}