剑指offer

1、判断栈的压入弹出序列

  关键:模拟,借用一个辅助栈,每次按照入栈顺序压入元素,并判断栈顶元素是否与出栈序列元素相等,若相等则循环出栈,最后若辅助栈为空则该出栈序列合理

class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        stack=[]
        j=0
        for i in range(len(pushed)):
            stack=append(pushed[i])
            while stack and stack[-1]==popped[j]:
                stack.pop()
                j+=1
        return not stack

 

2、二叉树的层序遍历

  关键:使用数据结构队列,collections.deque(),广度优先遍历

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        s=[]
        queue=collections.deque()
        queue.append(root)
        while queue:
            t=queue.popleft()
            if t:
                s.qppend(t.val)
            else:
                continue
            queue.append(t.left)
            queue.append(t.right)
        return s
    
#扩展:要求按层输出
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        queue=collections.deque()
        queue.append(root)
        r=[]
        while queue:
            l=len(queue)
            level=[]
            for i in range(l):
                t=queue.popleft()
                if t:
                    level.append(t.val)
                else:
                    continue
                queue.append(t.left)
                queue.append(t.right)
            if level:
                r.append(level)
        return r

 

3、二叉搜索树的后序遍历

  关键:递归,二叉搜索树节点为其左子树的上限,其右子树的下限,递归判断每棵子树是否符合条件

class Solution:
    def verifyPostorder(self, postorder: List[int]) -> bool:
        def func(i,j):
            if i>=j:
                return True
            p=i
            while postoerder[p]<postorder[j]:p+=1
            m=p
            while postorder[p]>postorder[j]:p+=1
            return p==j and func(i,m-1) and func(m,j-1)
        
        return func(0,len(postorder)-1)

 

4、二叉搜索树与双向链表

  关键:排序链表则需要中序遍历二叉树,并在修改每个节点的指针指向

class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        
        def dfs(root):
            if not root:
                return
            dfs(root.left)
            if self.pre:
                self.pre.right,root.left=root,self.pre
            else:
                self.head=root
            self.pre=root
            dfs(root.right)
        
        if not root:
            return
        self.pre=None
        dfs(root)
        self.head.left,self.pre.right=slef.pre,self.head

 

5、连续子数组最大和

  关键:将数组每个元素的值更新为前序和,最后输出最大前序和

  

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(1,len(nums)):
            nums[i]+=max(nums[i-1],0)
        return max(nums)

6、最长不含重复字符的子字符串

  关键:滑动窗口,注意窗口设置的细节,初始值设为1,且从数组第二个数开始遍历,最后更新start时要加上原来的start

  

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:
            return 0
        max_l=1
        start=0
        for end in range(1,len(s)):
            if s[end] not in s[start:end]:
                max_l=max(max_l,end-start+1)
            else:
                start+=s[start:end].index(s[end])+1
        return max_l
                
            

 

7、树的子结构

  关键:先在A中寻找与节点B相同的节点,找到后再依次判断B是否为该节点子结构

class Solution:
    def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        def recur(A,B):
            if not B: return True
            if not A or A.val!=B.val:return False
            return recur(A.left,B.left) and recur(A.right,B.right)
        return bool(A and B) and (recur(A,B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B))
    #判断B是否为A的子树或者B是否为A左子树的子树或B是否为A右子树的子树

 

8、二叉树的后序遍历

  关键:遍历找出根节点,根节点为左子树上限,右子树下限

class Solution:
    def verifyPostorder(self, postorder: List[int]) -> bool:
        def recur(i,j):
            if i>=j:
                return True
            p=i
            while postorder[p]<postorder[j]:
                p+=1
            m=p
            while postorder[p]>postorder[j]:
                p+=1
            return p==j and recur(i,m-1) and recur(m,j-1)
        
        return recur(0,len(postorder)-1)

 

9、二叉树中和为某一值的路径

  关键:先序遍历+路径记录

class Solution:
    def pathSum(self, root: TreeNode, target: int) -> List[List[int]]:
        res,path=[],[]
        def recur(root,tar):
            if noot root:return
            path.append(root.val)
            tar-=root.val
            if tar==0 and not root.left and not root.right:
                res.append(list(path))
            recur(root.left,tar)
            recur(root.right,tar)
            path.pop()
        recur(root,target)
        return res

 

10、和为target的全部整数序列

class Solution:
    def findContinuousSequence(self, target: int) -> List[List[int]]:
        r=[]
        i,j=1,1
        s=0
        while i<=target//2:
            if s<target:
                s+=j
                j+=1
            elif s>target:
                s-=i
                i+=1
            else:
                r.append(list(range(i,j)))
                s-=i
                i+=1
        return r

 

11、回文子串个数

  关键:枚举

class Solution:
    def countSubstrings(self, s: str) -> int:
        c=0
        for i in range(len(s)):
            for j in range(i+1,len(s)+1):
                if s[i:j]==s[i:j][::-1]:
                    c+=1
        return c

 

posted @ 2022-07-26 16:03  肥余  阅读(57)  评论(0)    收藏  举报