给定树的根结点指针TreeNode* root和结点的值int p,编写一个函数,寻找该二叉树中指定结点的下一个结点(即中序遍历的后继),并返回p结点的后继结点的值。保证结点的值是小于等于100000的正数且没有重复值,若不存在后继返回-1。
要寻找中序遍历的某个节点的下一个节点,肯定是要通过中序遍历实现的,题目中明确告诉我们节点的值没有重复,所以只要在中序遍历的过程中,某个节点的值等于p,则告诉递归者下一个要遍历的节点便是我们要找的节点,这个需要有个信号在多次递归之间进行传递消息,c++里用引用完全可以实现,只需要传递一个bool类型的引用便可。
class Successor {
public:
int findSucc(TreeNode* root, int p) {
// write code here
bool sign=0;
return findSucc1(root,p,sign);
}
int findSucc1(TreeNode* root,int p,bool &sign)
{
if(root==NULL)
return -1;
int left=findSucc1(root->left,p,sign);
if(left!=-1)
return left;
if(sign==true)
return root->val;
if(root->val==p)
sign=true;
return findSucc1(root->right,p,sign);
}
};
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Successor {
public int findSucc(TreeNode root, int p) {
boolean isFound = false;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while(cur!=null||!stack.isEmpty()){
while(cur!=null){
stack.add(cur);
cur = cur.left;
}
if(!stack.isEmpty()){
TreeNode q = stack.pop();
if(isFound) return q.val;
else if(q.val==p) isFound = true;
cur = q.right;
}
}
return -1;
}
}
中序遍历非递归算法
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Successor {
public:
int findSucc(TreeNode* root, int q) {
if(root==NULL) return -1;
stack<TreeNode*> stk;
TreeNode *p=root;
int k=1;
while(!stk.empty()||p)
{
if(p!=NULL)
{
stk.push(p);
p=p->left;
}
else
{
p=stk.top(); stk.pop();
if(k==0)
{
return p->val;
}
if(p->val==q)
{
k--;
}
p=p->right;
}
}
return -1;
}
};
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Successor {
//前一个节点,令此引用按照中序遍历的来移动,利用它来进行逆向移动
//即原来只能是 根→左 现在可以 左→根
private TreeNode pre = new TreeNode(-1);
public int findSucc(TreeNode root, int p) {
//空则表示没有
if (root == null)
return -1;
//一路向左,到达最左边的叶子
int left = findSucc(root.left, p);
if (left == -1) {
//最开始到达最左节点后,令pre指向该节点,同时root为pre的后继节点
////其后按照左根右的顺序移动
//如果上一个节点中找到p,则该节点后其后继节点
if (pre.val == p) {
return root.val;
}
pre = root; //如果前一个节点不是,则pre指向root的对象,
return findSucc(root.right, p);
}
//如果找不到则返回上一层的根节点,方向为 左→根
return left;
}
}
public int findSucc(TreeNode root, int p) {
// 非递归中序遍历,栈
Stack<TreeNode> list = new Stack<TreeNode>();
if(root == null || root.left == null){
return -1;
}
TreeNode cur = root;
boolean flag = false;
int res = -1;
while(cur != null || !list.isEmpty()){
if(cur != null){
list.push(cur);
cur = cur.left;
}else{
cur = list.pop();
System.out.println(cur.val);
if(flag){
res = cur.val;
break;
}
if(cur.val == p){
flag = true;
}
cur = cur.right;
}
}
return res;
}
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Successor {
List<Integer> list=new ArrayList();
public int findSucc(TreeNode root, int p) {
// write code here
int a=-1;
trvise(root);
for(int i=0;i<list.size();i++){
if(p==list.get(i)&&i!=list.size()-1){
a=list.get(i+1);
}
}
return a;
}
public void trvise(TreeNode root){
if(root!=null){
trvise(root.left);
list.add(root.val);
trvise(root.right);
}
}
}
中序遍历是先访问左孩子、再访问根节点、最后访问右孩子; 由于要先访问左孩子,因此在迭代过程中需要记录根节点; 又因为最后访问的根节点在回溯时最先访问到,所以要将所有根节点记录在栈中。
当栈不为空 || 当前节点不为空 的时候就一直作如下循环:
若当前节点不为空:则表示还没遍历到最左侧孩子的最底层;此时只需将当前节点入栈,并将当前节点指向左孩子即可。
public int findSucc(TreeNode root, int p) {
if ( root==null ) return -1;
Stack<TreeNode> stack = new Stack<>();
TreeNode curNode = root;
int lastNode = root.val;
while( curNode!=null || !stack.isEmpty() ){
if ( curNode==null ) {
curNode = stack.pop();
if ( lastNode==p ) {
return curNode.val;
}
lastNode = curNode.val;
curNode = curNode.right;
}
else {
stack.push( curNode );
curNode = curNode.left;
}
}
return -1;
}
public class Successor {
public int findSucc(TreeNode root, int p) {
// write code here
int prev = -1;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
if(!stack.isEmpty()){
root = stack.pop();
if(prev == p) return root.val;
prev = root.val;
root = root.right;
}
}
return -1;
}
} /*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Successor {
public:
vector<int> q;
void dfs(TreeNode* root){
//中序
if(root==NULL){
return ;
}
dfs(root->left);
q.push_back(root->val);
dfs(root->right);
}
int findSucc(TreeNode* root, int p) {
// write code here
dfs(root);
for(int i=0;i<q.size();i++){
if(q[i]==p){
if(i==q.size()-1)return -1;
return q[i+1];
}
}
return -1;
}
}; /*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Successor {
public:
int dfs(TreeNode* root,int p,bool &flag){
//中序
if(root==NULL){
return -1;
}
//先从左边找
int left=dfs(root->left,p,flag);
if(left!=-1){
//在左边找到了
return left;
}
if(flag==true){
//我的左儿子是p
return root->val;
}
if(root->val == p){
flag=true;
}
//左边没有找到的情况
return dfs(root->right,p,flag);
}
int findSucc(TreeNode* root, int p) {
// write code here
bool flag=false;
return dfs(root,p,flag);;
}
}; /*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Successor {
public:
int findSucc(TreeNode* root, int p) {
// write code here
bool flag=false;
int result=-1;
stack<TreeNode*> s;
TreeNode* temp=root;
//递归改循环
while(temp!=NULL||!s.empty()){
if(temp!=NULL){
//一直往左边压栈
s.push(temp);
temp=temp->left;
}else{
//左儿子没有了
temp=s.top();
s.pop();
if(flag){
//p的后继
result=temp->val;
break;
}
if(temp->val==p){
//找到p值
flag=true;
}
//查看右儿子
temp=temp->right;
}
}
return result;
}
}; // 1\. 想到了要用中序遍历。
// 2\. 因此只需要一个prev节点。在每次visit(currNode)后,令prev = currNode,然后在这之前判断prev即可
class Successor {
public:
int findSucc(TreeNode* root, int p) {
// write code here
stack stackA;
TreeNode *scan = root;
TreeNode *prev = NULL;
while(stackA.size() || scan)
{
while(scan)
{
stackA.push(scan);
scan = scan->left;
}
scan = stackA.top();
stackA.pop();
// 如果有业务代码,这里会有visit(scan);
// 因为prev刚开始=NULL,所以这里的判断让其忽略第一次
if(prev && prev->val == p)
return scan->val;
prev = scan;
if(scan->right)
scan = scan->right;
else
scan = NULL;
}
return -1;
}
};
class Successor {
public:
int findSucc(TreeNode* root, int p) {
stack<TreeNode*> s;
TreeNode* t = root;
bool flag = false;
while(!s.empty() || t){
if(t){
s.push(t);
t = t->left; }else{ t = s.top(); s.pop(); if(flag) return t->val; if(t->val == p) flag = true; t = t->right; } } return -1;
}
};
class Successor {
public:
bool flag = false;
int findSucc(TreeNode* root, int p) {
if (!root) { return -1; }
int a = findSucc(root->left, p);
if (-1 != a) { return a; }
if (flag) { return root->val; }
if (root->val == p) { flag = true; }
int b = findSucc(root->right, p);
if (-1 != b) { return b; }
return -1;
}
};
运行时间:6ms
占用内存:604k
//用队列来存
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Successor {
Queue<Integer> queue=new LinkedList<Integer>();
public int findSucc(TreeNode root, int p) {
if(p<0||p>100000) return -1;
findSuccCore(root);
while(!queue.isEmpty()){
int temp=queue.poll();
if(temp==p&&(!queue.isEmpty()))
return queue.poll();
}
return -1;
}
public void findSuccCore(TreeNode root){
if(root==null) return;
findSuccCore(root.left);
queue.offer(root.val);
findSuccCore(root.right);
}
} Java程序员面试金典解题:http://blog.csdn.net/sinat_22797429/article/details/75451784
//方法一:直接中序遍历,简单粗暴
ArrayList<Integer> result=new ArrayList<Integer>();
public int findSucc(TreeNode root, int p) {
findSuccByCenterSort(root);
for(int i=0;i<result.size();i++) if(result.get(i)==p) return i==result.size()-1?-1:result.get(i+1);
return -1;
}
public void findSuccByCenterSort(TreeNode root) {
if(root==null) return;
if(root.left!=null) findSuccByCenterSort(root.left);
result.add(root.val);
if(root.right!=null)findSuccByCenterSort(root.right);
}
//方法二,同方法一,节省内存空间
boolean flag=false;
int result=-1;
public int findSucc(TreeNode root, int p) {
findSuccByCenterSort(root,p);
return result;
}
public void findSuccByCenterSort(TreeNode root,int p) {
if(root==null) return;
if(root.left!=null) findSuccByCenterSort(root.left,p);
if(flag) {
flag=false;
result=root.val;
}
if(root.val==p) flag=true;
if(root.right!=null)findSuccByCenterSort(root.right,p);
}
class Successor {
public:
bool isfind=false;
int findSucc(TreeNode* root, int p) {
if(root==0) return -1;
int left=findSucc(root->left,p);
if(left>-1) return left;
if(isfind) return root->val;
if(root->val==p) isfind=true;
int right=findSucc(root->right,p);
if(right>-1) return right;
return -1;
}
};
//水货写个水程序,O(∩_∩)O哈哈~
class Successor {
public:
int findSucc(TreeNode* root, int p)
{
// write code here
vector<int> vec;
if(root==NULL || p<0) return -1;
helper(vec,root);
vec.push_back(-1);
int next=-1;
for(unsigned int i=0;i<vec.size();i++)
{
if(vec[i]==p)
{
next=vec[i+1];
}
}
return next;
}
void helper(vector<int>& vec,TreeNode* root)
{
if(root==NULL) return;
helper(vec,root->left);
vec.push_back(root->val);
helper(vec,root->right);
}
};
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Successor:
def findSucc(self, root, p):
if not root:
return -1
stack = []
ph = root
isFind = False
result = -1
while ph or stack:
while ph:
stack.append(ph)
ph = ph.left
if stack:
top = stack.pop()
if isFind:
result = top.val
break
if top.val == p:
isFind = True
ph = top.right
return result
//使用中序遍历,每次对遍历到的当前结点判断,如果val 为 p,则findFlag设置为真,下一个 //节点时,其值即为res,这个时候就可以将endFlag设置为真,也即无需继续遍历了 class Successor { public: int findSucc(TreeNode* root, int p) { bool findFlag = false, endFlag = false; int res = -1; searchBinary(root, p, findFlag, endFlag, res); return res; } void searchBinary(TreeNode* root, int p, bool &findFlag, bool &endFlag, int &res) { if(root->left != NULL) searchBinary(root->left, p, findFlag, endFlag, res); if(findFlag){ if(endFlag) return; endFlag = true; res = root->val; return; } if(root->val == p) findFlag = true; if(root->right != NULL) searchBinary(root->right, p, findFlag, endFlag, res); return; } };