Leetcode_链表

2.两数相加
19.删除链表的倒数第N个节点
21.合并两个有序链表
23. 合并K个排序链表
92. 反转链表 II
138. 复制带随机指针的链表
141. 环形链表
143. 重排链表
148. 排序链表
160. 相交链表
206. 反转链表
237. 删除链表中的节点
234. 回文链表
328. 奇偶链表
426. 将二叉搜索树转化为排序的双向链表
445. 两数相加 II

2.两数相加

题目描述:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
代码

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

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        if not l1:return l2
        if not l2:return l1
        tmp=ListNode(0)
        res=tmp
        flag=0
        while l1 or l2:
            tmpsum=0
            if l1:
                tmpsum+=l1.val
                l1=l1.next
            if l2:
                tmpsum+=l2.val
                l2=l2.next
            tmpres=(tmpsum+flag)%10
            res.next=ListNode(tmpres)
            flag=(tmpsum+flag)//10
            res=res.next
        if flag:
            res.next=ListNode(1)
        res=tmp.next
        return res
        

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

题目描述:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
两遍扫描:

# 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:
        m=0
        p=head
        q=head
        while p:
            m+=1
            p=p.next
        if m==1 and n==1:
            head=None
        elif m==n:
            head=head.next
        else:
            for i in range(1,m-n):
                q=q.next
            if n==1:
                q.next=None
            else:
                q.next=q.next.next
        return head

进阶(一遍扫描):

# 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:
        L=[]
        count=0
        while head:
            L.append(head)
            count+=1
            head=head.next
        if count==1:return None
        if L[-n].next==None:
            L[-n-1].next=None
            return L[0]
        else:
            L[-n].val=L[-n].next.val
            L[-n].next=L[-n].next.next
        return L[0]

21.合并两个有序链表

题目描述:将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
代码

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

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if not l1:return l2
        if not l2:return l1
        if l1.val<=l2.val:
            res=l1
            res.next=self.mergeTwoLists(l1.next,l2)
        else:
            res=l2
            res.next=self.mergeTwoLists(l1,l2.next)
        return res

迭代解法:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if not l1:return l2
        if not l2:return l1
        tmp=ListNode(0)
        res=tmp
        while l1 and l2:
            if l1.val<=l2.val:
                tmp.next=l1
                l1=l1.next
            else:
                tmp.next=l2
                l2=l2.next
            tmp=tmp.next
        if l1:
            tmp.next=l1
        if l2:
            tmp.next=l2
        return res.next
    

23.合并K个排序链表

题目描述:合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
代码

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

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        L=[]
        res=tmp=ListNode(0)
        for l in lists:
            while l:
                L.append(l.val)
                l=l.next
        for x in sorted(L):
            tmp.next=ListNode(x)
            tmp=tmp.next
        return res.next
        

141.环形链表

题目描述:给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
在这里插入图片描述
在这里插入图片描述
代码

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or not head.next:
            return False
        fast=head
        slow=head
        while fast and fast.next:
            fast=fast.next.next
            slow=slow.next
            if fast==slow:
                return True
        return False
        

148. 排序链表

题目描述:在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
在这里插入图片描述
代码:
这里的空间复杂度不是常数级的,常数级的解法后面在排序模块中列出

# 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:return None
        new=ListNode(0)
        res=new
        L=[]
        while head:
            L.append(head.val)
            head=head.next
        L.sort()
        while L:
            new.next=ListNode(L.pop(0))
            new=new.next
        return res.next

234. 回文链表

题目描述:请判断一个链表是否为回文链表。
思路:快慢指针找中点,然后翻转后半部分链表,判断前后是否一致,时间复杂度O(N),空间复杂度O(1).
在这里插入图片描述
代码

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or not head.next:return True
        fast,slow=head,head
        while fast and fast.next:
            fast=fast.next.next
            slow=slow.next
        cur=slow
        pre=None
        while cur:
            nex=cur.next
            cur.next=pre
            pre=cur
            cur=nex
        while pre and head:
            if pre.val!=head.val:
                return False
            pre=pre.next
            head=head.next
        return True

206. 反转链表

题目描述:反转一个单链表。
在这里插入图片描述
代码
感动哭了,这道题当初去刷剑指的时候怎刷都不会,复习了一下数据结构,终于可以独立写出来了,菜鸡感极而泣o(╥﹏╥)o

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:return head
        pre=head
        cur=head.next
        while cur:
            nex=cur.next
            cur.next=pre
            pre=cur
            cur=nex
        head.next=None
        return pre

138. 复制带随机指针的链表

题目描述:给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深拷贝。
在这里插入图片描述
思路:这道题剑指里面也有,还是不会,太惨了, 都得重新刷一遍,为什么我这么菜o(╥﹏╥)o

代码

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val, next, random):
        self.val = val
        self.next = next
        self.random = random
"""
class Solution(object):
    def copyRandomList(self, head):
        """
        :type head: Node
        :rtype: Node
        """
        if not head:return None
        clone=head
        while clone:
            node=Node(clone.val,None,None)
            node.next=clone.next
            clone.next=node
            clone=node.next
        clone=head
        while clone:
            node=clone.next
            if clone.random:
                node.random=clone.random.next
            clone=node.next
        clone=head
        new=head.next
        while clone.next:
            node=clone.next
            clone.next=node.next
            clone=node
        return new
        

92. 反转链表 II

题目描述:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
在这里插入图片描述
代码

哭了,这道题我花了一个多小时debug,结果还是看答案才会了,自己有想法,可是一直有bug,基础太菜,哭唧唧。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseBetween(self, head, m, n):
        """
        :type head: ListNode
        :type m: int
        :type n: int
        :rtype: ListNode
        """
        if not head:return
        new=ListNode(-1)
        new.next=head
        pre=new
        for _ in range(m-1):
            pre=pre.next
        start=pre.next
        tail=start.next
        for _ in range(n-m):
            start.next=tail.next
            tail.next=pre.next
            pre.next=tail
            tail=start.next
        return new.next

237. 删除链表中的节点

题目描述:请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
现有一个链表 – head = [4,5,1,9],它可以表示为:
在这里插入图片描述
思路:将当前节点的值和指针都修改为下一个节点的值和指针即可,相当于让当前节点冒充下一个节点,那么原来的当前节点被修改消除,原来节点的下一位节点因为没有被指针连接而失去意义

代码:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

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

328. 奇偶链表

题目描述:给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
在这里插入图片描述
思路:
代码:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def oddEvenList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head:return head
        odd=head
        even=head.next
        evenHead=even
        while even and even.next:
            odd.next=even.next
            odd=odd.next
            even.next=odd.next
            even=even.next
        odd.next=evenHead
        return head
  • 时间复杂度: O(n)O(n) 。总共有 nn 个节点,我们每个遍历一次。

  • 空间复杂度: O(1)O(1) 。我们只需要 4 个指针。

160. 相交链表

题目描述:编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在这里插入图片描述
代码

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        ha,hb=headA,headB
        while ha!=hb:
            if ha:
                ha=ha.next
            else:
                ha=headB
            if hb:
                hb=hb.next
            else:
                hb=headA
        return ha

426. 将二叉搜索树转化为排序的双向链表

题目描述:将一个二叉搜索树就地转化为一个已排序的双向循环链表。可以将左右孩子指针作为双向循环链表的前驱和后继指针。
为了让您更好地理解问题,以下面的二叉搜索树为例:
在这里插入图片描述
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
在这里插入图片描述
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
下图显示了转化后的二叉搜索树,实线表示后继关系,虚线表示前驱关系。
在这里插入图片描述

代码

"""
# Definition for a Node.
class Node:
    def __init__(self, val, left, right):
        self.val = val
        self.left = left
        self.right = right
"""
class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        def helper(node):
            nonlocal last, first
            if node:
                helper(node.left)
                if last:
                    last.right = node
                    node.left = last
                else:
                    first = node        
                last = node
                helper(node.right)
        
        if not root:
            return None
        first, last = None, None
        helper(root)
        last.right = first
        first.left = last
        return first

445. 两数相加 II

题目描述:给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
在这里插入图片描述
代码

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

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        if not l1:return l2
        if not l2:return l1
        def helper(root):
            T=root
            pre=root
            cur=pre.next
            while cur:
                nex=cur.next
                cur.next=pre
                pre=cur
                cur=nex
            T.next=None
            return pre
        l1=helper(l1)
        l2=helper(l2)
        flag=0
        new=ListNode(-1)
        new_head=new  
        while l1 or l2:
            cur_sum=0
            if l1:
                cur_sum+=l1.val
                l1=l1.next
            if l2:
                cur_sum+=l2.val
                l2=l2.next
            cur_val=(cur_sum+flag)%10
            flag=(cur_sum+flag)//10
            new.next=ListNode(cur_val)
            new=new.next
        if flag:
            new.next=ListNode(flag)
        return helper(new_head.next)
              

143. 重排链表

题目描述:给定一个单链表 L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
在这里插入图片描述
代码

在这里插入代码片

24. 两两交换链表中的节点
题目描述:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
代码

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

class Solution:
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        dummy = ListNode(-1)
        dummy.next, curr = head, dummy
        while curr.next and curr.next.next:
            first, second = curr.next, curr.next.next
            
            # swap two nodes
            first.next, second.next, curr.next = second.next, first, second
            
            # update to next iteration
            curr = curr.next.next
        return dummy.next
            

25.K个一组翻转链表

题目描述:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
在这里插入图片描述
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
代码

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

class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy
        tail = dummy
        while True:
            count = k
            while count and tail:
                count -= 1
                tail = tail.next
            if not tail: break
            head = pre.next
            while pre.next != tail:
                cur = pre.next # 获取下一个元素
                # pre与cur.next连接起来,此时cur(孤单)掉了出来
                pre.next = cur.next 
                cur.next = tail.next # 和剩余的链表连接起来
                tail.next = cur #插在tail后面
            # 改变 pre tail 的值
            pre = head 
            tail = head
        return dummy.next

61.旋转链表
题目描述:给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 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:
        if not head or not head.next:return head
        n=1
        old_tail=head
        while old_tail.next:
            old_tail=old_tail.next
            n+=1
        old_tail.next=head #先生成一个环
        new_tail=head
        for i in range(n-k%n-1):
            new_tail=new_tail.next
        new_head=new_tail.next
        new_tail.next=None
        return new_head

82. 删除排序链表中的重复元素 II
题目描述:给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现的数字。
在这里插入图片描述
代码

# 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:
        if not head:return None
        if head.next and head.next.val==head.val:
            while head.next and head.next.val==head.val:
                head=head.next
            return self.deleteDuplicates(head.next)
        else:
            head.next=self.deleteDuplicates(head.next)
        return head

83.删除排序链表中的重复元素
题目描述:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3
代码

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

class Solution:
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head:return None
        p=head
        while p and p.next:
            while p and p.next and p.val==p.next.val:
                p.next=p.next.next
            p=p.next
        return head

86.分隔链表
题目描述:给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
在这里插入图片描述
代码

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

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        if not head or not head.next:return head
        before=before_head=ListNode(0)
        after=after_head=ListNode(-1)
        while head:
            if head.val<x:
                before.next=ListNode(head.val)
                before=before.next
            else:
                after.next=ListNode(head.val)
                after=after.next
            head=head.next
        before.next=after_head.next
        after.next=None
        return before_head.next
        

92. 反转链表 II
题目描述:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
在这里插入图片描述
代码

# 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 not head:return None
        stack=[]
        new=ListNode(0)
        res=new
        while head:
            stack.append(head.val)
            head=head.next
        stack[m-1:n]=reversed(stack[m-1:n])
        while stack:
            new.next=ListNode(stack.pop(0))
            new=new.next
        return res.next

142.环形链表 Ⅱ
题目描述:给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
在这里插入图片描述
代码

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next or not head.next.next:
            return None
        slow=head.next
        fast=head.next.next
        while fast and fast.next and fast!=slow:
            fast=fast.next.next
            slow=slow.next
        if fast==slow:
            fast=head
            while fast!=slow:
                fast=fast.next
                slow=slow.next
            return fast
        return None      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值