记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
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