面试题21:栈的压入、弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列{1,2,3,4,5}是某栈的压栈序列,序列{4,5,3,2,1}是该压栈的对应的一个弹出序列,但{4,3,5,1,2}就不可能是该压栈序列的弹出序列。
思路:
判断一个序列是不是栈的弹出序列的规律:如果下一个弹出的数字刚好是栈顶数字,直接弹出;如果下一个弹出的数字不在栈顶,则把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止;如果所有数字都压入栈后仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。
代码实现:
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
if(pushV.size() == 0)
return false;
vector<int> stack;//int类型的容器
for(int i = 0, j = 0; i < pushV.size();)
{
stack.push_back(pushV[i++]);
while(j < popV.size() && stack.back() == popV[j])
{
stack.pop_back();
j++;
}
}
return stack.empty();
}
};
面试题22:从上往下打印二叉树
题目:不分行从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。例如,输入图4.6中的二叉树,则依次打印出8,6,10,5,7,9,11。二叉树节点的定义如下:
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
思路:
每次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的节点,重复前面的打印操作,直至队列中所有的节点都被打印出来。
代码实现:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root) {
vector<int> que;//返回值要求是整型的容器类型
if(!root)
return que ;
std::deque<TreeNode*>dequeTreeNode;
dequeTreeNode.push_back(root);
while(dequeTreeNode.size())
{
TreeNode *pNode = dequeTreeNode.front();
que.push_back(pNode->val);
dequeTreeNode.pop_front();
// printf("%d",pNode->val);
if(pNode->left)
dequeTreeNode.push_back(pNode->left);
if(pNode->right)
dequeTreeNode.push_back(pNode->right);
}
return que ;
}
};
面试题23:二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路:
在后序遍历得到的序列中,最后一个数字是树的根节点的值。数组中前面的数字可以分为两部分:第一部分是左子树节点的值,它们都比根节点的值小;第二部分是右子树节点的值,它们都比根节点的值大。
代码实现:
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
return bst(sequence,0,sequence.size()-1);
}
bool bst(vector<int> sequence,int begin,int end)
{
if(sequence.empty() || begin > end)
return false;
int root = sequence[end];//后序遍历最后一个元素作为根元素
int i = begin;//将首元素序号赋值给i
for(;i<end;++i)
{
if(sequence[i]>root)//左子节点小于根节点,右子节点大于根节点
break;
}
for(int j = i;j < end; ++j)
{
if(sequence[j]<root)
return false;
}
bool left = true;
if(i > begin)
left=bst(sequence,begin,i-1);
bool right = true;
if(i < end - 1)
right=bst(sequence,i,end - 1);
return left&&right;
}
};