算法套路六——删除链表元素
算法示例LeetCode203. 移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
本题与本专栏算法套路四中的算法示例二:LeetCode92. 反转链表 II一样,可能删除头结点也可能不删除头结点,遇到这种情况需要定义dummy哨兵节点
,如不理解可前往[算法套路四]中的算法示例二阅读
直接定义cur = dummy,对cur进行遍历,若cur.next.val等于val则使cur.next = cur.next.next
class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode:
dummy = ListNode(next=head) #添加一个虚拟节点
cur = dummy
while cur.next!=None:
if cur.next.val == val:
cur.next = cur.next.next #删除cur.next节点
else:
cur = cur.next
return dummy.next
算法练习一:LeetCode19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
可能会删除头结点,也可能不删除头结点,因此我们与示例一样需要添加dummy哨兵结点
要找到倒数第n个节点,我们可以先定义前后指针before,after=dummy,before指针先向前移动n个位置,之后before与after一起向前移动,当before指向最后一个元素时,after指向倒数第n个元素
func removeNthFromEnd(head *ListNode, n int) *ListNode {
var dummy *ListNode=&ListNode{
Next:head}
before,after:=dummy,dummy
for i:=0;i<n;i++{
before=before.Next
}
for before.Next!=nil{
after=after.Next
before=before.Next
}
after.Next=after.Next.Next
return dummy.Next
}
算法练习二:LeetCode83. 删除排序链表中的重复元素
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
当 cur.val 和 cur.next.val 相等时说明需要去重,则将 cur的下一个指针指向下一个的下一个,这样就能达到去重复的效果
如果不相等则 cur移动到下一个位置继续循环
func deleteDuplicates(head *ListNode) *ListNode {
if head==nil{
return head
}
cur:=head
for cur.Next!=nil{
if cur.Val==cur.Next.Val{
cur.Next=cur.Next.Next
}else{
cur=cur.Next
}
}
return head
}
算法练习三:LeetCode82. 删除排序链表中的重复元素 II
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列
本题与上一题相比唯一的不同是由于重复元素都要删除,可能会删除头结点,也可能不删除头结点,因此我们与示例一样需要添加dummy哨兵结点
,此外还要注意循环退出条件,因为一次需要判断cur后的两个结点,所以需要cur.Next != nil && cur.Next.Next != nil
func deleteDuplicates(head *ListNode) *ListNode {
dummy := &ListNode{
Next: head}
cur := dummy
for cur.Next != nil && cur.Next.Next != nil {
val := cur.Next.Val
if cur.Next.Next.Val == val {
for cur.Next != nil && cur.Next.Val == val {
cur.Next = cur.Next.Next
}
} else {
cur = cur.Next
}
}
return dummy.Next
}
算法练习四:LeetCode237. 删除链表中的节点
有一个单链表的 head,我们想删除它其中的一个节点 node。给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
给定节点的值不应该存在于链表中。
链表中的节点数应该减少 1。
node 前面的所有值顺序相同。
node 后面的所有值顺序相同。
我们不知道node前面的节点,那么显然无法直接删除node节点,但我们可以将node.next.val赋值node.val,这样删除node.next节点即可
func deleteNode(node *ListNode) {
node.Val=node.Next.Val
node.Next=node.Next.Next
}