5.28 力扣 字符匹配解码

1171 从链表中删去总和值为零的连续节点
5.28 力扣 字符匹配解码_第1张图片
在这里插入图片描述
前缀和 用字典 前缀和存指针
两个结点的前缀和相等,说明两个结点之间和为0、
如果后面前缀和等于前面的前缀和,则用后面的结点覆盖前面的结点
然后重构结点
申请当前节点的前缀和sum为key,当前节点指针为value的哈希表

class Solution:
    def removeZeroSumSublists(self, head: ListNode) -> ListNode:
        seen=dict()
        dummy=ListNode(0)
        dummy.next=head
        cur=head
        seen[0]=dummy
        pre=0
        while cur:
            pre+=cur.val
            seen[pre]=cur
            cur=cur.next
        pre=0
        cur=dummy
        while cur:
            pre+=cur.val
            cur.next=seen[pre].next
            cur=cur.next
        return dummy.next

面试题 02.08. 环路检测
5.28 力扣 字符匹配解码_第2张图片

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow,fast=head,head
        while  fast and fast.next:
            slow,fast=slow.next,fast.next.next
            if slow==fast:
                break
        if not fast or not fast.next:
            return None
        pre=head
        while pre!=fast:
            pre,fast=pre.next,fast.next
        return pre

面试题06. 从尾到头打印链表
5.28 力扣 字符匹配解码_第3张图片
最简单的把链表数据读入列表,然后翻转列表
递归法:先走至链表末端,回溯时依次将节点值加入列表 ,这样就可以实现链表值的倒序输出
在这里插入图片描述
5.28 力扣 字符匹配解码_第4张图片

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        return self.reversePrint(head.next) + [head.val] if head else []

面试题36. 二叉搜索树与双向链表 同426
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
“head” 表示指向链表中有最小元素的节点。
5.28 力扣 字符匹配解码_第5张图片
5.28 力扣 字符匹配解码_第6张图片

class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        def dfs(cur):
            if not cur:
                return 
            dfs(cur.left)
            if self.pre:
                #右指针指向后继节点,左指针指向前驱节点
                self.pre.right,cur.left=cur,self.pre
            else:
                #左叶子节点是头结点
                self.head=cur
            self.pre=cur
            dfs(cur.right)
        if not root:
            return
        self.pre=None
        dfs(root)
        #头结点的前驱是尾节点,尾节点的后继是头结点
        self.head.left,self.pre.right=self.pre,self.head
        return self.head

10. 正则表达式匹配
5.28 力扣 字符匹配解码_第7张图片
5.28 力扣 字符匹配解码_第8张图片
如果没有星号(正则表达式中的 * ),问题会很简单——我们只需要从左到右检查匹配串 s 是否能匹配模式串 p 的每一个字符。
当模式串中有星号时,我们需要检查匹配串 s 中的不同后缀,以判断它们是否能匹配模式串剩余的部分
如果模式串p中有星号,它会出现在第二个位置,即pattern[1] 。这种情况下,我们可以直接忽略模式串中这一部分,或者删除匹配串s的第一个字符,前提是它能够匹配模式串当前位置字符,即 pattern[0] 。如果两种操作中有任何一种使得剩下的字符串能匹配,那么初始时,匹配串和模式串就可以被匹配。

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        if not p:
            return not s
        #下一位为‘*’时,如果第一位不匹配,则直接判断s 和p[2:]是否匹配,因为‘*’前面一位可以出现0次
        #如果第一位匹配或者为'.'(匹配任意字符),则判断s[1:] 和p(实例2),s,p[2:](实例4)是否匹配
        if len(p)>1 and p[1]=='*':
            if s and (p[0]=='.' or s[0]==p[0]) :
                return self.isMatch(s,p[2:]) or self.isMatch(s[1:],p)
               #如果第一位不匹配,跳过p的前两位,从p[2:]开始继续判断是否与s匹配
            return self.isMatch(s,p[2:])
        #第一项匹配且第二位不是‘*’,则按位判断
        if s and (p[0]==s[0] or p[0]=='.'):
            return self.isMatch(s[1:],p[1:])
        return False

44. 通配符匹配
5.28 力扣 字符匹配解码_第9张图片
5.28 力扣 字符匹配解码_第10张图片
带记忆的递归:
5.28 力扣 字符匹配解码_第11张图片
5.28 力扣 字符匹配解码_第12张图片
5.28 力扣 字符匹配解码_第13张图片

class Solution:
    #将多个连续*用一个*替代
    def remove_stars(self,p):
        if p=='':
            return p
        p1=[p[0]]
        for x in p[1:]:
            if p1[-1]!='*' or p1[-1]=='*' and x!='*':
                p1.append(x)
        return ''.join(p1)
    def helper(self,s,p):
        dp=self.dp
        if (s,p) in dp:
            return dp[(s,p)]
        if s==p or p=='*':
            dp[(s,p)]=True
        elif not s or not p:
            dp[(s,p)]=False
        elif s[0]==p[0] or p[0]=='?':
            dp[(s,p)]=self.helper(s[1:],p[1:])
        elif p[0]=='*':
            #不匹配字符或者匹配一个到多个
            dp[(s,p)]=self.helper(s,p[1:]) or self.helper(s[1:],p)
        else:
            dp[(s,p)]=False
        return dp[(s,p)] 
    def isMatch(self, s: str, p: str) -> bool:
        p=self.remove_stars(p)
        #构建哈希表存储已经检查过的(s,p)
        self.dp={}
        return self.helper(s,p)

面试题04:二维数组中的查找240. 搜索二维矩阵 II
5.28 力扣 字符匹配解码_第14张图片
左下角元素 为所在列最大元素,所在行最小元素
如果 左下角元素 大于了目标值,则目标值一定在该行的上方, 左下角元素所在行可以消去。
如果 左下角元素 小于了目标值,则目标值一定在该列的右方, 左下角元素所在列可以消去。
5.28 力扣 字符匹配解码_第15张图片

class Solution:
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        i,j=len(matrix)-1,0
        while i>=0 and j<len(matrix[0]):
            if matrix[i][j]==target:
                return True
            elif matrix[i][j]>target:
                i-=1
            elif matrix[i][j]<target:
                j+=1
        return False

74. 搜索二维矩阵
5.28 力扣 字符匹配解码_第16张图片
时间复杂度:O(m+n)

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        i,j=len(matrix)-1,0
        while i>=0 and j<len(matrix[0]):
            if matrix[i][j]==target:
                return True
            elif matrix[i][j]<target:
                j+=1
            elif matrix[i][j]>target:
                i-=1
        return False

二分查找:
输入的 m x n 矩阵可以视为长度为 m x n的有序数组。
5.28 力扣 字符匹配解码_第17张图片
在这里插入图片描述

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        m=len(matrix)
        if m==0:
            return False
        n=len(matrix[0])
        #二分查找
        left,right=0,m*n-1
        while left<=right:
            pivort=(right+left)//2
            pivort_e=matrix[pivort//n][pivort%n]
            if pivort_e==target:
                return True
            elif pivort_e>target:
                right=pivort-1
            else:
                left=pivort+1
        return False

387. 字符串中的第一个唯一字符
5.28 力扣 字符匹配解码_第18张图片

class Solution:
    def firstUniqChar(self, s: str) -> int:
        mark=defaultdict(int)
        for i in range(len(s)):
            mark[s[i]]+=1
        p=None
        for i,v in mark.items():
            if v==1:
                p=i
                break
        for c in range(len(s)):
            if p==s[c]:
                return c
        return -1

394. 字符串解码
5.28 力扣 字符匹配解码_第19张图片
5.28 力扣 字符匹配解码_第20张图片
字符由内而外,利用栈先进后出

class Solution:
    def decodeString(self, s: str) -> str:
        res,stack,n='',[],0
        for c in s:
            if c=='[':
            #将当前res和倍数入栈,并将其重置为0,用于保存[]内的数据
                stack.append([res,n])
                res=''
                n=0
            #字符串的数字要挨个位置叠加
            elif c.isdigit():
                n=n*10+int(c)
            elif c==']':
                last_res,cur_n=stack.pop()
                res=last_res+cur_n*res
            else:
                res+=c
        return res

你可能感兴趣的:(力扣,字符串,数据结构,python)