leetcode刷题 链表相关 python

链表相关 python

  • —————剑指offer—————
    • easy
      • 1)JZ6 从尾到头打印链表
      • 2)JZ24 反转链表
      • 3)JZ25 合并两个排序的链表
      • 4)JZ52 两个链表的第一个公共结点
      • 5)JZ23 链表中环的入口结点(mid)
      • 6)JZ22 链表中倒数最后k个结点
      • 7)JZ18 删除链表的结点
      • 8)JZ83 删除排序链表中的重复元素
    • mid
      • 9)JZ35 复杂链表的复制

—————剑指offer—————

easy

1)JZ6 从尾到头打印链表

题目描述
leetcode刷题 链表相关 python_第1张图片
*注意输入的是结点,输出的是数组

①方法一:打入栈,逆序输出

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

python3

class Solution:
    def printListFromTailToHead(self , listNode: ListNode) -> List[int]:
        # write code here 牛客里默认py3的格式
        stack = []
        while listNode:
            stack.append(listNode.val)
            listNode = listNode.next
        return stack[::-1]

listnode是头节点,List[list]返回一个列表

python2 的默认自定义函数的格式是

class Solution:
    def blaba(self, listnode):

liatnode头结点名

②方法二:递归 (但很有可能超过最大递归层数而报错)

class Solution:
    def printListFromTailToHead(self , listNode: ListNode) -> List[int]:
        # write code here
        return self.printListFromTailToHead(listNode.next) + [listNode.val] if listNode else []

注意
Ⅰ 方法自身间的回溯需要 + self

Ⅱ 同一个类,不同对象间的互相调用回溯需要 + self

Ⅲ 方法内的函数递归自身不需要self(如print方法里我再自定义一个函数进行递归便不需要self)

这里的第一参数self表示创建的是类实例

Ⅳ 注意这个if else的使用, blablabla = a 的执行是在if的条件下,否则就 = else里的那个东西

Ⅴ 注意[]与()的使用,第一遍自己打的时候,listnode.val外面写成了(),这样是错的

Ⅵ 注意 + 是拼接的意思

Ⅶ 注意使用递归可能会因为超过最大递归层数而报错,谨慎使用(此题在牛客使用递归没有通过)
leetcode刷题 链表相关 python_第2张图片

2)JZ24 反转链表

题目描述

给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点
在这里插入图片描述
leetcode刷题 链表相关 python_第3张图片
leetcode刷题 链表相关 python_第4张图片

其实输入都是一样的,输入一个链表的头节点

①方法一:最简单的思路,取出值,再装入新的链表里

数组切片,但是需要额外的空间存储链表
时O(n) 空O(n)

class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        stack = [] #把链表逆序存入一个数组里(从题 6学来)
        while head:
            stack.append(head.val)
            head = head.next
        stack = stack[::-1] #逆序数组
     #学会怎么去新建一个结点
        node = ListNode(0) #定义一个结点,给它填入值0,这个结点当作伪头结点
        p = node # p是指向这个结点的指针
        for num in stack: #意思是num从前往后取一遍stack里的值
            p.next = ListNode(num) #往后链接新的结点,填入stack的值
            p = p.next
        return node.next #输出真正开始表达含义的头结点,node.next才能取出真正的值

②方法二:在1的基础上简化一下,把列表想象成一个栈,把切片操作改成列表的pop操作

class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        res = []
        while head:
            res.append(head.val)
            head = head.next
        #注意,这里就不需要逆序操作了,等着下面的pop即可
        node = ListNode(0)
        p = node
        while res:#当res列表不为空的时候
            p.next = ListNode(res.pop()) #注意这里pop函数要加()的
            p = p.next
        return node.next

注意:

Ⅰ 把列表名设置成stack老报错,改成别的就正常了,嗯,注意不要设置成特殊指代单词
Ⅱ res.pop() 默认pop尾部的那个

③方法三:双指针

时O(n) 空O(1)

class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        cur = head #定义一个指针,和head所指向的位置一样,即头结点
        pre = None #定义一个指针,指向空,即None,理解为Null
        while cur: #直到cur==None就退出
        # 从左往后看去设计,不是从右往左看,要不然全乱套了
            tmp = cur.next

你可能感兴趣的:(leetcode,python)