在二叉搜索树中找公共祖先的时候很容易的就可以判断pq节点分别在根节点的哪边,而在普通二叉树中需要自己实现,实现递归搜索的时候被哪里return搞昏了,递归的正确思考方式:
如果下面这两点是成立的,我们就知道这个递归对于所有的 n 都是正确的:
当 n=0,1 时,结果正确;
假设递归对于 n 是正确的,同时对于 n+1 也正确。
def tra (root,tar):
if not root:return False
if root==tar:return True
return tra(root.left,tar) or tra(root.right,tar)
最后样例里有一个一直只有左子节点的树,超时了,面向样例优化了一下:只在左右节点都存在的时候判断目标节点在左子树还是右子树,否则直接进入仅有的那个子树
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
def tra (root,tar):
if not root:return False
if root==tar:return True
return tra(root.left,tar) or tra(root.right,tar)
cur = root
while True:
if cur == p:return cur
if cur == q:return cur
elif not cur.left:
cur = cur.right
elif not cur.right:
cur = cur.left
elif tra(cur.left,p) and tra(cur.left,q):
cur = cur.left
elif tra(cur.right,p) and tra(cur.right,q):
cur = cur.right
else:
return cur
就用以前二叉搜索树的思路给每个节点标号也是一样的原理。
还是回溯,和ip分划基本一样,但是要注意每次temp要手动建新的,和ip分划是可变变量和不可变变量的区别。
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
clen = len(candidates)
tmp = []
def tra(tmp,target,sum, candidates):
if len(res)<150:
if sum<target:
for num in candidates:
temp = tmp[0:]
tempsum = sum
temp.append(num)
tempsum+=num
tra(temp,target,tempsum,candidates)
elif sum==target:
tmp.sort()
if tmp not in res:
res.append(tmp)
else:
return
tra(tmp,target,0,candidates)
return res
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
if not head or not head.next or not head.next.next:return False
cur1,cur2 = head,head
while cur1 and cur2 and cur1 != cur2:
cur1 = cur1.next
cur2 = cur2.next
cur2 = cur2.next
if cur2==cur1:return True
else:return False
用快慢指针更好 ,若无环慢指针追不上快指针,若有环入环后快指针会追上慢指针