先看一个例子,这是leetcode上一道中等难度的题。
思路:
根据中序遍历去找下一个节点就好,设置一个pre节点记录前一个位置。提供两种方法吧。
第一种是设置类成员pre和ans,这种方法较为简单直接,因为不必考虑递归的返回值问题。
class Solution {
TreeNode pre,res;
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
f(root,p);
return res;
}
public void f(TreeNode root,TreeNode p){
if(root==null) return;
f(root.left,p);
if(pre==p) {
res=root;
}
pre=root;
f(root.right,p);
}
}
第二种是仅设置类成员pre,这种方法稍微复杂一点点,需要考虑递归的返回值问题。其实也不复杂,递归嘛,首先要清楚递归函数的意义即找到目标节点,传入根节点,左子树找一下,接受一下结果,右子树找一下,接受一下结果,肯定只有一边找到吧,谁为空就返回另外一边即可。
class Solution {
TreeNode pre;
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
return f(root,p);
}
public TreeNode f(TreeNode root,TreeNode p){
if(root==null) return null;
TreeNode left=f(root.left,p);
if(pre==p) {
pre=root;
return root;
}
pre=root;
TreeNode right=f(root.right,p);
return left==null?right:left;
}
}
总结:其实树的问题都是一样的,核心都是遍历,三行代码,具体到题目无非是修改下遍历过程的操作,比如是打印输出,还是加入一个集合,等,有了框架,剩下的只是细节而已。