自用力扣刷题记录(Python,链表、哈希表)

这篇博客主要探讨了链表和哈希表相关的算法问题。在链表部分,涵盖了移除特定值节点、删除指定节点、删除倒数第N个节点、扁平化多级双向链表、旋转链表、两两交换节点、反转链表以及K个一组翻转等操作。在哈希表部分,讨论了查找重复元素、平方数之和、求交集、最长连续序列、快乐数、键盘行、单词规律、k-diff数对、同构字符串、分数到小数以及复制带随机指针的链表等题目。这些内容涉及到了链表和哈希表的多种应用和算法实现。
摘要由CSDN通过智能技术生成


顺序参考:https://leetcode-cn.com/circle/article/48kq9d/

四、链表

题目分类 题目编号
链表的删除 203、237、19
链表的遍历 430
链表的旋转与反转 61、24、206、 92、25
链表高精度加法 2、445
链表的合并 21 、23

203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
    	#用ret记录答案链表的开头,tmp用来制作链表,最后返回ret
        tmp = ret = ListNode() 
        while head:
            if head.val != val:
                tmp.next = head
                tmp = tmp.next
            head = head.next
        tmp.next = None
        return ret.next

237. 删除链表中的节点

请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点 。

# 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

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
思路:设两个指针,中间相差n,后面的指针到最后一个元素时,前面的指针正好指到改删除的元素的前一个

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        left = right = head
        count = 0 
        while count < n:
            right = right.next
            count += 1
        if not right:
            return head.next
        while right.next:
            left = left.next
            right = right.next
        if left.next:
            left.next = left.next.next
        return head

430. 扁平化多级双向链表

在这里插入图片描述

"""
# Definition for a Node.
class Node:
    def __init__(self, val, prev, next, child):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child
"""

class Solution:
    def flatten(self, head: 'Node') -> 'Node':
        cur = head
        tmp = None
        while cur:
            if cur.child:#如果需要铺平
                tmp = cur.next#记录有孩子节点的下一个节点
                p = self.flatten(cur.child)#展平 
                cur.next = p #将当前节点指向铺平的链表
                p.prev = cur #铺平链表和之前链表连起来
                cur.child = None
                q = cur #连起来之后找到铺平列表的尾部
                while q.next:
                    q = q.next
                q.next = tmp#找到后与原节点的下一个节点连起来
                if tmp is not None: tmp.prev = q#如果没下一个节点就不用连prev了
                cur = tmp
            else:#不需要铺平直接下一个
                cur = cur.next
        return head

61. 旋转链表

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

在这里插入图片描述

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def rotateRight(self, head: ListNode, k: int) -> ListNode:
        if head == None or k == 0:return head
        l = 1
        cur = head
        while cur.next is not None:#计算节点个数
            cur = cur.next
            l += 1
        cur.next = head#顺便连成个环
        count = l - k%l#计算移动几个
        if count == 0:#不移动把环断掉
            cur.next = None
            return head
        for i in range(count):#移动
            cur = cur.next
        ans = cur.next
        cur.next = None#移动到地方了断环
        return ans
            

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

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
在这里插入图片描述
思路:用栈构造一个新列表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if not (head and head.next):
            return head
        p = ListNode(-1)#构造一个新的链表
        cur,head,stack = head,p,[]#答案返回head.next
        while cur and cur.next:
            stack.append(cur)
            stack.append(cur.next)
            cur = cur.next.next
            p.next = stack.pop()
            p.next.next = stack.pop()
            p = p.next.next
        #原链表长度为奇数时最后还剩下一个数
        if cur:
            p.next = cur
        else:
            p.next = None
        return head.next

206. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
思路:两个指针,一前一后直接翻转(改变next的指向方向),需要中间变量做存储

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not(head and head.next):return head
        cur = head.next
        pre = head
        pre.next = None
        while cur:
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        return pre

92. 反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

在这里插入图片描述
指向 left 左边元素的指针 pre ,它表示未翻转的链表,需要把当前要翻转的链表结点放到 pre 之后。
cur 指向当前要翻转的链表结点。
nxt 指向 cur.next ,表示下一个要被翻转的链表结点。
tail 指向已经翻转的链表的结尾,用它来把已翻转的链表和剩余链表进行拼接。
在这里插入图片描述

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def reverseBetween(self, head, left, right):
        count = 1
        dummy = ListNode(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值