237. 删除链表中的节点 leetcode.cn/problems/de…
有一个单链表的 head,我们想删除它其中的一个节点 node。
给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。
链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。
删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
给定节点的值不应该存在于链表中。
链表中的节点数应该减少 1。
node 前面的所有值顺序相同。
node 后面的所有值顺序相同。
public class ListNode {
public var val: Int
public var next: ListNode?
public init(_ val: Int) {
self.val = val
self.next = nil
}
}
class Solution {
func deleteNode(_ node: ListNode?) {
node?.val = (node?.next?.val)!
node?.next = node?.next?.next
}
}
206. 反转链表 ttps://leetcode.cn/problems/reverse-linked-list/description/
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
通过递归和迭代两种方法实现
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
}
}
// 递归
func reverseList(_ head: ListNode?) -> ListNode? {
if head == nil || head?.next == nil { // 空链表或者只有一个结点直接return
return head
}
let newHead = reverseList(head?.next) // 已经翻转
head?.next?.next = head // 已经翻转过的链表的最后一个结点(即head.next)的next指向头结点
head?.next = nil // 将头结点的next置为nil
return newHead
}
// 1 2
// 1.next.next = 1, 1.next = null -> 2.next = 1, 1.next = null
// 1 2 3
// head = 3
// 1.next.next = 1, 1.next = null -> 2.next = 1, 1.next = null
// 2.next.next = 2, 2.next = null -> 3.next = 2, 2.next = null
// 1 2 3 4
// head = 4
// 1.next.next = 1, 1.next = null -> 2.next = 1, 1.next = null
// 2.next.next = 2, 2.next = null -> 3.next = 2, 2.next = null
// 3.next.next = 3, 3.next = null -> 4.next = 3, 3.next = null
// 迭代
func reverseList2(_ head: ListNode?) -> ListNode? {
if head == nil || head?.next == nil { // 空链表或者只有一个结点直接return
return head
}
var tempHead = head
var newHead: ListNode?
while tempHead != nil {
let temp = tempHead?.next
tempHead?.next = newHead
newHead = tempHead
tempHead = temp
}
return newHead
}
测试代码:
let s = Solution()
var node0 = ListNode(0, nil)
var node1 = ListNode(1, node0)
var node2 = ListNode(2, node1)
var node3 = ListNode(3, node2)
// 初始链表:3 -> 2 -> 1 -> 0 -> nil
//s.reverseList2(node3)
// 翻转后链表:0 -> 1 -> 2 -> 3 -> nil
141. 环形链表 leetcode.cn/problems/li…
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
class Solution_141 {
// 快慢指针
func hasCycle(_ head: ListNode?) -> Bool {
if head == nil || head?.next == nil {
return false
}
var slow = head
var fast = head?.next
while fast != nil, fast?.next != nil {
slow = slow?.next
fast = fast?.next?.next
// === 是比较两个对象的地址是否相等,不能用==是因为listNode不满足equalable协议
if slow === fast {
return true
}
}
return false
}
}
测试代码:
let s = Solution_141()
var node0 = ListNode(0, nil)
var node1 = ListNode(1, node0)
var node2 = ListNode(2, node1)
var node3 = ListNode(3, node2)
print(s.hasCycle(node3)) // false
node0.next = node2
print(s.hasCycle(node3)) // true
203. 移除链表元素 leetcode.cn/problems/re…
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
class Solution_203 {
func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? {
if head == nil {
return head
}
let newHead = ListNode(-1, head) // 增加一个虚拟头结点
var prev: ListNode? = newHead
while prev?.next != nil {
if prev?.next?.val == val {
prev?.next = prev?.next?.next
} else {
prev = prev?.next
}
}
return newHead.next // 虚拟头结点的next一定是head
}
}
测试代码:
let s = Solution_203()
var node0 = ListNode(6, nil)
var node1 = ListNode(5, node0)
var node2 = ListNode(4, node1)
var node3 = ListNode(3, node2)
var node4 = ListNode(6, node3)
var node5 = ListNode(2, node4)
var node6 = ListNode(1, node5)
let head = s.removeElements(node6, 1)
83. 删除排序链表中的重复元素 leetcode.cn/problems/re…
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
class Solution_83 {
func deleteDuplicates(_ head: ListNode?) -> ListNode? {
if head == nil || head?.next == nil {
return head
}
var current = head
// 链表已经排序,故相同的元素一定相连
while current != nil, current?.next != nil {
if current?.val == current?.next?.val {
current?.next = current?.next?.next
} else {
current = current?.next
}
}
return head
}
}
测试代码:
// 删除排序链表中的重复元素
let s = Solution_83()
var node0 = ListNode(3, nil)
var node1 = ListNode(3, node0)
var node2 = ListNode(2, node1)
var node3 = ListNode(1, node2)
var node4 = ListNode(1, node3)
let head = s.deleteDuplicates(node4)
876. 链表的中间结点 leetcode.cn/problems/mi…
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
class Solution_876 {
func middleNode(_ head: ListNode?) -> ListNode? {
// 快慢指针
if head == nil || head?.next == nil {
return head
}
var fast = head
var slow = head
while fast?.next != nil {
fast = fast?.next?.next
slow = slow?.next
}
return slow
}
}
// 1 2 3 4 5 6 7 8 9 0
// 3 5 7 9 *
// 2 3 4 5 6