当前位置:   article > 正文

leetcode 中的链表简单题 python3_python3 listnode

python3 listnode

目录:

基本使用 //

21题 合并有序链表 //

83题 删除有序链表重复元素 //

141题 环形链表 //

160题 相交链表 //

203题 移除链表元素//

206题 反转链表 //

基本使用:

之前没有学过链表,leetcode最近在做简单题,才发现链表的定义,元素之间是通过节点连接的。链表类定义以后的函数调用解释:

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, val=0, next=None):
  4. # self.val = val
  5. # self.next = next
  6. p = ListNode()
  7. l1: ListNode
  8. #l1 就是链表里的指针所在的位置以及之后的元素
  9. #若此链表为[1, 2, 3]
  10. #l1 = [1, 2, 3]
  11. #l1.next = [2, 3]
  12. l1.val #默认第0个元素 例子中为1
  13. l1 = l1.next #指针后移
  14. #此时l1.val 为2
  15. #l1.next = [3]
  16. p.next = ListNode(l1.val) #这个元素值赋给链表p的下一个元素

21题 合并有序链表

将两个有序链表合并为一个新的升序链表

  1. class Solution:
  2. def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
  3. p = ListNode()
  4. ans = p
  5. while l1 and l2:
  6. if l1.val < l2.val:
  7. p.next = ListNode(l1.val)
  8. l1 = l1.next
  9. else:
  10. p.next = ListNode(l2.val)
  11. l2 = l2.next
  12. p = p.next
  13. if l1:
  14. p.next = l1
  15. else:
  16. p.next = l2
  17. return ans.next
  18. # p.next不被直接返回是因为p此时指针已经到了最后一个元素
  19. #而提前设置的ans和p指向同一个链表,那么使用ans.next返回整个链表

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

1. 设置prev, cur = head, head.next, prev与head指向同一个链表 ;

2. perv.val == cur.val 时 prev跳过下一个值(cur.val) 直接保存next为cur.next 即 prev.next = cur.next ;  (指到后继节点的后继节点来删除本身的后继节点)

3. 若非如此,prev后移一个即 prev = cur. ;

4. 无论如何,cur = cur.next 后移往前进着

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, val=0, next=None):
  4. # self.val = val
  5. # self.next = next
  6. class Solution:
  7. def deleteDuplicates(self, head: ListNode) -> ListNode:
  8. if not head:
  9. return head
  10. perv, cur = head, head.next
  11. while cur:
  12. if perv.val == cur.val:
  13. perv.next = cur.next
  14. else:
  15. perv = cur
  16. cur = cur.next
  17. return head

141题 环形链表

看了某站up的讲解,才知道环形链表的意思...

环形通常出现在有循环处,那么一般就可用这两种常见办法。同类题型可见202题 快乐数。

方法一: 又顺便学了哈希表,哈希表在python里就是dict和set. dict相当于保存2个list,一个元素本身 一个下标(映射)。set保存1个list,元素本身。这个题可以使用哈希表存储,环形链表的环会存在于已建立的哈希表内,因此True条件为:node in s

  1. class Solution:
  2. def hasCycle(self, head: ListNode) -> bool:
  3. if not head: return False
  4. s = set()
  5. node = head
  6. while node:
  7. if node in s:
  8. return True
  9. else:
  10. s.add(node)
  11. node = node.next
  12. return False

方法二:快慢指针。还是很好理解的

  1. class Solution:
  2. def hasCycle(self, head: ListNode) -> bool:
  3. if not head: return False
  4. fast = slow = head
  5. while fast and fast.next:
  6. slow = slow.next
  7. fast = fast.next.next
  8. #总是快一步,那么进入循环后总会在第二圈赶上slow,即相等
  9. if slow == fast:
  10. return True
  11. return False

160题 相交链表

方法一:用哈希表存储headA的所有后续节点,遍历headB,若遍历到指针存在于此哈希表,则说明存在。(这个是自己想出来的~)

  1. class Solution:
  2. def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
  3. s = set()
  4. nodeA = headA
  5. nodeB = headB
  6. while nodeA:
  7. s.add(nodeA)
  8. nodeA = nodeA.next
  9. while nodeB:
  10. if nodeB in s:
  11. return nodeB
  12. nodeB = nodeB.next
  13. return None

方法二:双指针。(来源用户 Krahets 题解)假设headA有a个节点,headB有b个节点,相交于c节点,设置2个指针:指针A从headA开始遍历,结束后遍历B至节点处需要走 (a+b-c) 个节点;指针B从headB开始遍历,结束后遍历A至节点处需要走 (b+a-c) 个节点,指针会相遇。返回此时指针A,若不相遇则A会遍历完 a+b 所有节点指向null. 时间复杂度O(a+b), 空间复杂度O(1) 常数大小的额外空间。

  1. class Solution:
  2. def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
  3. A, B = headA, headB
  4. while A != B:
  5. A = A.next if A else headB
  6. #若headA遍历完成则A=headB开始遍历
  7. B = B.next if B else headA
  8. return A

看到评论有人问为什么 A = A.next if A else A = headB 会报错,因为A = 赋值+赋值条件,后面是一个模块,等于语句 if A: A = A.next else: A = headB.  ifelse语句在赋值使用当然不需要再加赋值号啦...

203题 移除链表元素

思路很简单,保证第一个节点满足要求,然后进入判断循环,如果后继节点等于val就跳过后继节点赋值给next,否则直接指针后移。注意一点在保证头节点满足要求之后

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/209796
推荐阅读
相关标签