【LeetCode】链表专题

目录

注意:

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

237. 删除链表中的节点

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

61. 旋转链表

24. 两两交换链表中的节点

206. 反转链表

92. 反转链表 II

160. 相交链表

142. 环形链表 II

148. 排序链表


注意:

和b站up主大雪菜一起刷题https://www.bilibili.com/video/BV1jt411J7tC

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

思路:

  • 首先,链表题一般可以直接画图得到思路
  • 要删除倒数第N个节点的话,我们实际需要找到的是倒数第N+1个节点的位置,然后令其的next=next.next
  • 由于可能头结点被删除,则可以添加一个虚节点指向头结点
  • 题目要求只扫描一次完成,设置双指针,第一个first指针从虚节点起往后走N步,然后用last指针从虚节点起和first同步往后移,当first指向了最后一个节点,则last所指的指针即为倒数N+1各节点
  • 注意返回的时候不要返回head,因为可能头结点已经被删掉了,而应该返回dummy.next
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode()
        dummy.next = head
        first,last = dummy,dummy
        k = 0
        # first先走
        while first:
            first = first.next
            k += 1
            if k == n:
                break
        # last开始
        while first.next:
            first = first.next
            last = last.next
        last.next = last.next.next
        return dummy.next

237. 删除链表中的节点

思路:

  • 这道题是需要你完成一个函数,这个函数只给定需要删除的节点node
  • 这个时候可以利用下一个节点的值将当前值覆盖,达到删除的目的,因为需要删除的节点绝对不是末尾的节点
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        node.val = node.next.val
        node.next = node.next.next

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

思路:

  • 重复元素要保留第一个即可,那么只需判断当前节点的下一个节点值与当前节点的值是否相等,相等的话则将下一个节点进行删除,否则当前节点后移
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        cur = head
        while cur:
            # 重复元素
            if cur.next and cur.next.val == cur.val:
                cur.next = cur.next.next
            else:# 不同的元素
                cur = cur.next
        return head

61. 旋转链表

思路:

  • 旋转末尾k个位置的数字到头结点之前,这时候要考虑k的大小问题,k可能超过链表长度,所以需要取模
  • 可以利用前面的双指针的方法找到倒数第k+1个位置,和最后一个位置,然后进行处理即可
  • 注意k的大小,和链表为空的情况
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def rotateRight(self, head: ListNode, k: int) -> ListNode:
        n = 0
        first = head
        while first:
            n += 1
            first = first.next
        if n == 0 or not head:
            return head
        k = k%n
        first,second = head,head
        while k:
            k -= 1
            first = first.next
        while first.next:
            first = first.next
            second = second.next
        first.next = head
        head = second.next
        second.next = None
        return head

24. 两两交换链表中的节点

思路:

  • 画图分析
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        dummy = ListNode(-1)
        dummy.next = head
        p = dummy
        while p.next and p.next.next:
            a,b = p.next,p.next.next
            p.next = b
            a.next = b.next
            b.next = a
            p = a
        return dummy.next

206. 反转链表

思路:

  • 思路,关键让头尾中间的节点互相的指向对调
  • 最后让头指针的next改为None即可
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head:
            return []
        a,b = head, head.next
        while b:
            # 防止断链
            c = b.next
            b.next = a
            a, b = b, c
        head.next = None
        return a

92. 反转链表 II

思路:

  • 和上一题思路类似,这题主要在上一题的基础上加了限制范围
  • 那就要找到四个位置,a:m-1位置,b:m位置,c:n位置,d:n+1位置
  • 对b~c里相邻节点进行指针方向的转换,和上一题思路一样
  • a指向c,b指向d即可完成
  • 由于可能会对头结点的位置进行改变,建立一个虚拟节点dummy
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
        if m==n:
            return head
        dummy = ListNode(-1)
        dummy.next = head
        a,c = dummy,dummy
        while m-1:
            m -= 1
            a = a.next
        # print("a:{}".format(a.val))
        while n:
            n -= 1
            c = c.next
        # print("c:{}".format(c.val))
        b, d = a.next, c.next
        p, q = b, b.next
        while q!=c:
            o = q.next
            q.next = p
            p, q = q, o
        q.next = p
        b.next = d
        a.next = c
        return dummy.next

160. 相交链表

思路:

  • 当相遇的时候,走过的路程是等长的,把握好这一核心点
  • 如果是两条没有相交的链表,最后都会等于none
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        Pa, Pb = headA, headB
        while Pa!=Pb:
            if not Pa:
                Pa = headB
            else:
                Pa = Pa.next
            if not Pb:
                Pb = headA
            else:
                Pb = Pb.next
        return Pb
        

142. 环形链表 II

思路:

  • 快慢指针的一个妙用,fast每次走两步,slow每次走一步
  • 第一次相遇之后,slow从起点再次走,和fast同步往后移一步,既可以找到环的入口
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        fast, slow = head, head
        while fast:
            fast = fast.next
            slow = slow.next
            if fast:
                fast = fast.next
            else:
                break
            # 第一次相遇
            if fast == slow:
                slow = head
                while fast!=slow:
                    fast = fast.next
                    slow = slow.next
                else:
                    return fast
        return None

148. 排序链表

思路:

  • 这道题由于限制了时间复杂度和空间复杂度,这道题适合使用归并排序解决
  • 归并排序的关键点是写好merge函数,分而治之的思想,当我们分到只有一个节点的两个链表进行排序就很简单了。再依次往上就可以。
  • 【不过题目要求的空间复杂度为常数级别,使用了递归就肯定不是,得改成循环,我暂时只会写递归的版本,先给自己埋个坑,以后看懂闫神的代码再改吧】
  • 快慢指针不仅可以用来在链表中找环,也可以用来在链表里找到终点。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        # 寻找中间节点
        if not head or not head.next:
            return head
        fast, slow, pre= head, head, head
        while fast and fast.next:
            pre = slow
            fast = fast.next.next
            slow = slow.next
        # 从中间节点断开
        pre.next = None
        return self.merge(self.sortList(head), self.sortList(slow))

    
    def merge(self, h1, h2):
        # 建立虚拟头节点
        dummy = ListNode(-1)
        cur = dummy
        while h1 and h2:
            if h1.val < h2.val:
                cur.next = h1
                h1 = h1.next
            else:
                cur.next = h2
                h2 = h2.next
            cur = cur.next
        if h1:
            cur.next = h1
        if h2:
            cur.next = h2
        return dummy.next

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
旅游社交小程序功能有管理员和用户。管理员有个人中心,用户管理,每日签到管理,景点推荐管理,景点分类管理,防疫查询管理,美食推荐管理,酒店推荐管理,周边推荐管理,分享圈管理,我的收藏管理,系统管理。用户可以在微信小程序上注册登录,进行每日签到,防疫查询,可以在分享圈里面进行分享自己想要分享的内容,查看和收藏景点以及美食的推荐等操作。因而具有一定的实用性。 本站后台采用Java的SSM框架进行后台管理开发,可以在浏览器上登录进行后台数据方面的管理,MySQL作为本地数据库,微信小程序用到了微信开发者工具,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得旅游社交小程序管理工作系统化、规范化。 管理员可以管理用户信息,可以对用户信息添加修改删除。管理员可以对景点推荐信息进行添加修改删除操作。管理员可以对分享圈信息进行添加,修改,删除操作。管理员可以对美食推荐信息进行添加,修改,删除操作。管理员可以对酒店推荐信息进行添加,修改,删除操作。管理员可以对周边推荐信息进行添加,修改,删除操作。 小程序用户是需要注册才可以进行登录的,登录后在首页可以查看相关信息,并且下面导航可以点击到其他功能模块。在小程序里点击我的,会出现关于我的界面,在这里可以修改个人信息,以及可以点击其他功能模块。用户想要把一些信息分享到分享圈的时候,可以点击新增,然后输入自己想要分享的信息就可以进行分享圈的操作。用户可以在景点推荐里面进行收藏和评论等操作。用户可以在美食推荐模块搜索和查看美食推荐的相关信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值