您的位置:首页 > 其它

LeetCodeOJ_199_Binary Tree Right Side View

2015-06-12 10:55 375 查看
答题链接

题目:

Given a binary tree, imagine yourself standing on therightside of it, return the values of the nodes you can see ordered from top tobottom.

For example:Given the following binary tree,

1 <---

/ \

2 3 <---

\ \

5 4
<---

You should return[1,
3,4].

分析:
刚拿到这道题,我一直在以深度优先的方法进行思考,即从根节点搜索到叶子节点,但是,搜索到叶子节点之后呢?如何返回重新搜索其他枝叶呢?不得而解。
后来,我以宽度优先的方法进行思考,一层一层的判断,处理完一层,扔掉一层,再处理下一层,这有点先进先出的感觉,自然而然,我引入了队列。
具体方法可描述为:

初始化,将根节点root入队(注意判断root是否为空);

将队尾节点(最右边)的value值添加到result中;

对于当前队列中的所有节点,记录其节点个数size,从先到后依次将它们的左、右节点入栈,然后删除原本的size个节点(即扔掉处理完的当前层,存入下一层的所有节点);

跳转到(2),循环执行,直到队列为空,即所有节点都被处理过了。

代码:
宽度优先:

<span style="font-size:14px;">/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
#include <queue>
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> result;
queue<TreeNode*> qNode;
if(root!=NULL)
qNode.push(root);
while(!qNode.empty())
{
result.push_back(qNode.back()->val);

int qSize=qNode.size();
for(int i=0;i<qSize;i++)
{
TreeNode* lNode=qNode.front()->left;
if(lNode!=NULL)
qNode.push(lNode);
TreeNode* rNode=qNode.front()->right;
if(rNode!=NULL)
qNode.push(rNode);
qNode.pop();
}

}

return result;

}
};
</span>


结果:



方法2:
此时,我再回过头去看我最初的思路——深度优先法,类比思考,我发现了解决搜索到叶子节点后返回重新搜索其他枝叶的办法,那就是引入栈。
具体方法为:
(1)当根节点不为空时,将根节点入栈;
(2)先访问栈顶节点的右子树,如果其不为空,则右子树入栈;反之,访问栈顶元素的左子树,如果不为空,则入栈,如果左子为空,则说明栈顶节点是叶子节点;
(3)当访问到叶子节点时,需要重新定位接下来的搜索位置,定位方法为:将当前的栈顶节点curNode出栈,并保存,如果curNode是现在新的栈顶节点的右子树且现在栈顶节点的左子树不为空,则新的搜索位置为现在栈顶节点的左子树,将现在栈顶节点的左子树入栈,跳转到(2)继续执行,反之,继续出栈,直到栈为空为止。
(4)循环执行(2)(3),直到栈为空为止。
此外,为了判断哪些元素应该存入result中,我定义了一个变量level存储当前处理的节点所在的层数,由于每一层最右边的节点的val值会存入result中,所以,一旦出现result.size()<level,则说明当前访问的是新的一层,则将当前节点的val值存入result中。

代码:

深度优先:

<span style="font-size:14px;">/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
#include <stack>
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> result;
stack<TreeNode*> sNode;
//level代表当前搜索到的层数
int level=0;

if(root!=NULL)
{
sNode.push(root);
level++;
result.push_back(root->val);
}

while(!sNode.empty())
{
TreeNode* curNode=sNode.top();
TreeNode* rNode=sNode.top()->right;
TreeNode* lNode=sNode.top()->left;
//当前访问节点的右儿子存在
if(rNode!=NULL)
{
sNode.push(rNode);
level++;
if(result.size()<level)//说明当前搜索到的节点位于全新的一层,则将该节点的值插入result中
result.push_back(rNode->val);
}
//当前访问节点的右儿子不存在,左儿子存在
else if(lNode!=NULL)
{
sNode.push(lNode);
level++;
if(result.size()<level)
result.push_back(lNode->val);
}
//当前访问的是叶子节点
else
{
sNode.pop();
level--;
while(!sNode.empty())
{
if((curNode==sNode.top()->right)&&(sNode.top()->left!=NULL))
{
sNode.push(sNode.top()->left);
level++;
break;
}
else
{
curNode=sNode.top();
sNode.pop();
level--;
}

}
if(result.size()<level)
result.push_back(sNode.top()->val);
}

};
return result;
}
};

</span>


结果:



附件:
1、c++标准库的栈和队列
From:/article/1354405.html
相关头文件:#include<stack>

#include<queue>
栈定义: stack<int> stk;
队列定义: queue<int> q;
栈操作:
s.empty() 如果栈为空返回true,否则返回false
s.size() 返回栈中元素的个数
s.pop() 删除栈顶元素但不返回其值
s.top() 返回栈顶的元素,但不删除该元素
s.push() 在栈顶压入新元素
队列操作:
q.empty() 如果队列为空返回true,否则返回false
q.size() 返回队列中元素的个数
q.pop() 删除队列首元素但不返回其值
q.front() 返回队首元素的值,但不删除该元素
q.push() 在队尾压入新元素
q.back() 返回队列尾元素的值,但不删除该元素


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: