链表 83. 删除排序链表中的重复元素 203. 移除链表元素 19. 删除链表的倒数第N个节点

83. 删除排序链表中的重复元素

  • 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例:

输入: 1->1->2->3->3
输出: 1->2->3

思路:

  1. 考虑特殊情况——链表为空,直接返回。
  2. 使用一个指针,将指针next的值与当前值进行判断,若相等,将next再向后指一位。
  3. 若不想等,指针向后移动到不相等的位置。

代码实现

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        # 链表为空时,直接返回
        if head is None:
            return head

        l = head
        while l.next:
            if l.next.val == l.val:
                l.next = l.next.next
            else:
                l = l.next
        return head

203. 移除链表元素

  • 删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

思路:

想要删除某个节点,就必须找到这个节点的前一个节点,把前一个节点的指针改变,即指向下下一个就可以达到删除的目的了。
在这里插入图片描述

代码实现1

class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        l = ListNode(-1)
        l.next = head
        pre, cur = l, l.next
        
        while cur:
            if cur.val == val:
                cur = cur.next
            else:
                pre.next = cur
                cur = cur.next
                pre = pre.next
            pre.next = None
        return l.next

代码实现2

class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        p = ListNode(-1)
        # 因为要删除的可能是链表的第一个元素,所以用一个h节点来做处理
        # 最后只要返回h的下一个节点即可
        p.next,h = head,p
        # 注意遍历的条件是p.next不为空
        while p.next:
			# 如果p的下一个节点的值==val
			# P就指向下下一个,这就删掉了指定的节点
            if p.next.val==val:
                p.next = p.next.next
				# 注意这里的continue
				# 因为循环最后还有一个P=p.next,所以要跳过
                continue
			# 不用continue用else的方式也是可以的
            p = p.next
        return h.next

19. 删除链表的倒数第N个节点

  • 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2. 给定的 n 保证是有效的。
当删除了倒数第二个节点后,链表变为 1->2->3->5.

思路1:两次遍历

  1. 先遍历一次链表,求出链表的总长度。
  2. 根据总长度-n,计算出要删除节点的位置。
  3. 第二次遍历的时候,在要删除的节点的前一个节点处,将此节点的next指针指向next.next节点,达到删除节点的目的。

代码实现

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        # 增加特殊节点,处理要删除的节点位于首节点的情况
        h = ListNode(-1)
        # 将特殊节点连接到head上,且放置游标指针于head上,作计算链表长度使用
        h.next, cur = head, head
        # 定义第二次遍历时的指针,放置到特殊节点位置,最终需要返回特殊节点的next节点
        l = h
        length = 0
        # 第一次遍历,求得列表长度
        while cur:
            cur = cur.next
            length += 1
            
        # 找到要删除节点的位置
        node = length-n
        
        # 若要删除的节点位于链表中或链表尾,则通过循环将l移动到要删除节点的前一个节点
        while node > 0:
            l = l.next
            node -= 1
        # 此处处理两种情况
        # 一、要删除的节点位于首节点(即node=0),将首节点的next指针指向next.next节点
        # 二、退出循环后,l节点位于要删除节点的前一个节点,将此节点的next指针指向next.next节点,完成删除
        l.next = l.next.next
        return h.next

思路2:一次遍历

  1. 定义两个指针pre和cur,cur先走n步,接着pre和cur同时往前走,当cur指针走到链表末尾时,pre指针刚好走到要删除的节点的前一个位置。
  2. 将pre节点的next指针指向next.next节点,就可以完成删除操作了。
    在这里插入图片描述

代码实现

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        # 增加特殊节点,处理要删除的节点位于首节点的情况
        h = ListNode(-1)
        h.next = head
        # 定义两个指针pre和cur
        pre = h
        cur = head
        while cur:
        	# cur指针先走n步,此时,cur处于要删除节点的后一个节点
            if n > 0:
                cur = cur.next
                n -= 1
                continue
            # cur和pre同时向前走,cur走到头时(cur = None),pre位于要删除节点的前一个节点,退出循环
            cur = cur.next
            pre = pre.next
        # 将pre节点的next指针指向next.next节点,完成删除操作
        pre.next = pre.next.next
        return h.next
发布了51 篇原创文章 · 获赞 4 · 访问量 3512

猜你喜欢

转载自blog.csdn.net/yhhuang17/article/details/104757801
今日推荐