题目描述
给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数。如何实现?
题目解析
思路:
-
能不能只取出栈底元素而不改变栈?
- [1,2,3]拿到1,栈内保持[2,3]
-
能做到1的话,那能不能再把取出的元素放回?
- [2,3]->[2,3,1]
-
重复递归是不是可以实现整个栈的逆序?
单独看第一个问题的话,其实用递归应该比较好想到,大概的思路如下:通过递归函数的入栈,得到数据栈最底层的1,将这个1一层层返回。其余的数据放回栈内(图中并没有画出,避免线杂乱)
int getDown(std::stack<int> stack){
//取出栈顶元素
int res = stack.top(); stack.pop();
//如果栈空,表明这个元素为栈底元素
if(stack.empty()){
return res;
}
//递归获得每次的栈底[1,2,3]的1;[2,3]的2
int last = getDown(stack);
stack.push(res); //栈不为空,要将这个元素放回栈
return last;
}
那这只是实现了第一步,接下来怎么办呢?这就是我觉得这个题比较经典的地方,用到了双重递归。
void reverse(std::stack<int>& stack){
if(stack.empty()){
return;
}
int i=getDown(stack);//取出栈底元素
reverse(stack);//对剩余的元素逆序
stack.push(i);//将栈底元素压入,此时栈底元素变为栈顶
}
也就是说,这里用到了两个递归函数,一个获取并移除栈底元素,另一个负责逆序。其实俩个递归思路基本一致。
int getDown(std::stack<int> & stack){
//取出栈顶元素
int res = stack.top(); stack.pop();
//如果栈空,表明这个元素为栈底元素
if(stack.empty()){
return res;
}
//递归获得每次的栈底[1,2,3]的1;[2,3]的2
int last = getDown(stack);
stack.push(res); //栈不为空,要将这个元素放回栈
return last;
}
void reverse(std::stack<int>& stack){
if(stack.empty()){
return;
}
int i=getDown(stack);//取出栈底元素
reverse(stack);//对剩余的元素逆序
stack.push(i);//将栈底元素压入,此时栈底元素变为栈顶
}
int main(){
std::stack<int> stack;
stack.push(1);
stack.push(2);
stack.push(3);
reverse(stack);
// reverse(stack);
}