LeetCode-深度优先搜索-Hard

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步




99. Recover Binary Search Tree 恢复二叉搜索树

解题思路:
中序遍历可以发现节点的错误
在二叉树中交换了两个节点 在中序遍历中可能有三种倒序情况
如123456
1.124356 出现4->3 交换4,3
2.153426 出现5->3 4->2 交换 5,2
3.125436 出现 5->4 4->3 交换 5,3
因为只交换了两个节点 我们只要找到这两个节点n1,n2
交换这两个节点的值就可以了
可以发现第一个n1就是第一次出现倒序情况中的pre
n2就是最后一次出现倒序情况中的本节点node

class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

def recoverTree(root):
    """
    :type root: TreeNode
    :rtype: void Do not return anything, modify root in-place instead.
    """
    global n1,n2,pre
    n1=n2 = None
    pre = None
    
    def findtwo(node):
        global n1,n2,pre
        if node:
            findtwo(node.left)
            if pre and pre.val > node.val:
                if not n1:
                    n1 = pre
                n2 = node
            pre = node
            findtwo(node.right)
            
    findtwo(root)
    n1.val,n2.val = n2.val,n1.val
    return root

124. Binary Tree Maximum Path Sum 二叉树中的最大路径和

解题思路:
递归思路
题目中 关键是 完成一条链路可以不经过根节点
我们考虑每一个节点时 可以分两种情况
一种是经过这个点后完成完整路线 跟该节点父节点没有关系了
另一种是将经过这个点的最大值传递给上一层,并非完整链路
这两种情况的区别就是是否能够将左右子树的值都加在一起
如果加了那么这条路径已经完成无法传给上一层
需要一个全局变量res来存储最大路径的值
getMax返回的是非完整链路最大值
左子树最大值left
右子树最大值right
完成一条完整链路 将大于0的left,right和node.val加在一起 =>linkval
判断linkval是否为最大 保存
接下来返回到该节点为止的最大非完整路线值
若左右子树返回的大于零
则加上较大的值返回max(left,right)

class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        
def maxPathSum(root):
    """
    :type root: TreeNode
    :rtype: int
    """
    global res
    res = 0
    if not root:
        return res
    res = root.val
    
    def getMax(root):
        global res
        num = 0 
        if not root:
            return num
        
        num = root.val
      
        left = getMax(root.left)
        right = getMax(root.right)
        
        tmp = num
        if left>0:
            tmp += left
        if right>0:
            tmp += right
        
        m = max(left,right)
        if m > 0:
            num += m
        
        res = max(res,tmp)

        return num
    
    getMax(root)
    return res

301. Remove Invalid Parentheses 删除无效的括号

解题思路:
(和)分开来考虑
处理(时 从头开始计数(+1 )-1 如果小于0了 就说明)多余了 此时可以从当前位置往前的所有)中去除一个来保证序列的正确性
继续递归从下一个位置开是检查 这里lastj是记录上一次去除的位置 之后去除要在这个位置之后防止重复
当(处理完成后 将其倒序 同样检查)

def removeInvalidParentheses(s):
    """
    :type s: str
    :rtype: List[str]
    """
    global ret
    ret = []
    
    def remove(s,lasti,lastj,ch):
        global ret
        count =0
        for i in range(lasti,len(s)):
            if(s[i] == "(" or s[i]==")"):
                if s[i]==ch:
                    count-=1
                else:
                    count+=1
            if count>=0:
                continue
            for j in range(lastj,i+1):
                if(s[j] == ch and (j == lastj or s[j - 1] != ch) ):
                    news = s[:j]+s[j+1:]
                    remove(news,i,j,ch)
            return
        ress = s[::-1]
        if ch==")":
            return remove(ress,0,0,"(")
        else:
            ret.append(ress)
    
    remove(s,0,0,")")
    return ret

329. Longest Increasing Path in a Matrix 矩阵中的最长递增路径

解题思路:
从每个点的上下左右检查 可以储存检查过的点的最大值 当到达这个点时直接返回最大值即可

def longestIncreasingPath(matrix):
    """
    :type matrix: List[List[int]]
    :rtype: int
    """
    ret = 0
    x=len(matrix)
    if x>0:
        y=len(matrix[0])
    else:
        return 0
    record = [[0 for i in range(y)] for j in range(x)]
    def deal(posx,posy,lastVal):
        if (posx < 0 or posy < 0 or posx >= x or posy >= y):
            return 0
        if (matrix[posx][posy] > lastVal):
            if (record[posx][posy] != 0):
                return record[posx][posy]
            down = deal(posx + 1, posy, matrix[posx][posy]) + 1
            up = deal(posx - 1, posy, matrix[posx][posy]) + 1
            right = deal(posx, posy + 1, matrix[posx][posy]) + 1
            left = deal(posx, posy - 1, matrix[posx][posy]) + 1
            record[posx][posy] = max(left,right,down,up)
            return record[posx][posy]
        return 0
            
        
    for i in range(x):
        for j in range(y):
            ret = max(ret,deal(i,j,-1))
    return ret

472. Concatenated Words 连接词

解题思路:
要包含合成词 必须要含有三个以上的单词
合成词肯定是若干个短的词拼接而成 所以我们可以先从短的词开始分析
使用一个set来存储已经考虑过的list中较短的单词 当以后再次需要分析这个单词时可直接返回True
使用set可以减少用in查找时的耗时

def findAllConcatenatedWordsInADict(words):
    """
    :type words: List[str]
    :rtype: List[str]
    """
    ret = []
    if len(words)<3:
        return ret
    words.sort(key=lambda x:len(x))
    exist_dict = set()
    def check(w):
        if w in exist_dict:
            return True
        for i in range(1,len(w)):
            if w[:i] in exist_dict and check(w[i:]):
                return True
            
        return False
   
    for w in words:
        if check(w):
            ret.append(w)
        exist_dict.add(w)
    return ret

猜你喜欢

转载自blog.csdn.net/zkt286468541/article/details/83961901