栈、队列算法题

  • 用栈实现队列,完成队列的Push和Pop操作。 队列中的元素为int类型

//思路

栈只能从栈顶出入,队列从队首出,队尾入,借助两个栈:栈1的顶为队尾,栈2的顶为队首
push 从队尾压入一个元素,从s1压入,栈空和非空情况一样,无返回值
pop 从队首一个弹出元素,s2不空时队首在s2栈顶,s2空时队首在s1栈底,需要先把s1中所有元素依次弹入s2,然后弹出s2栈顶
注意从A中弹出所有元素压入B时,因为A数组改变,所以需要先把数组长度存下来,再使用保存的值控制for循环
如果s1空,队列为空,pop弹出null

var stack1 = [],
  // var stack1 = [],
  stack2 = []; //定义两个栈
//入队,修改原数组,无返回值
function push(node) {
  // write code here
  stack1.push(node); //压入栈1
}
//出队,修改原数组,返回出队元素
function pop() {
  // write code here
  //栈2不空,返回栈2栈顶元素
  if (stack2.length !== 0) return stack2.pop();
  //栈2空,返回栈1栈底元素
  if (stack2.length === 0) {
    //栈1空,返回空
    if (stack1.length === 0) return null;
    //栈1不空,将栈1元素全部放入栈2,然后返回栈顶元素
    let len =stack1.length;//for循环修改了stack1数组,所以要先保存len作为循环的计数器
    for (let i = 0; i < len; i++) {
      stack2.push(stack1.pop());
    }
    return stack2.pop();
  }
}
  • 用队列实现栈

//队列:先进先出。简单来说,就是有一个数组,通过 push() 推进每个元素,通过 shift() 推出第一个元素,这种形式就是队列。
//栈:先进后出。简单来说,就是有一个数组,通过 push() 推进每个元素,通过 pop() 推出最后一个元素,这种形式就是栈。
如果小伙伴们还是不理解,那么我们讲讲两个例子:

队列:饭堂打饭。我们需要排队,先到的排前面,打完饭后可以先走。
栈;俄罗斯套娃,或者叠罗汉。先进的需要最后出,要不然取不出来,或者罗汉直接倒了。
最后,根据这个思路,我们可以轻易求解。

var MyStack = function() {
  this.stask = [];
};

MyStack.prototype.push = function(x) {
  this.stask[this.stask.length] = x;
};

MyStack.prototype.pop = function() {
  let arr = this.stask;
  let last = this.stask.length - 1;
  let temp = arr[last];
  this.stask.length = this.stask.length - 1;
  return temp;
};

MyStack.prototype.top = function() {
  let arr = this.stask;
  let last = this.stask.length - 1;
  return arr[last];
};

MyStack.prototype.empty = function() {
  let arr = this.stask;
  if (!arr.length) {
    return true;
  } else {
    return false;
  }
};

 

  •  定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数、pop()、push(),时间复杂度应为O(1)

//思路

时间复杂度应为O(1)所以应该保存每次栈压入元素之后的最小值,新建一个stkMin,和stk同步
push——栈元素是第一个,入栈元素是当前最小值时,stkMin压入node,否则压入stkMin栈顶元素(之前的最小值依然是最小值)
pop——stkMin和stk同步出栈
min——返回stkMin栈顶元素


var stk = [];
var stkMin = [];
function push(node) {
  // write code here
  stk.push(node);
  stkMin.length === 0 || node < stkMin[stkMin.length - 1]
? stkMin.push(node) //stkMin空/node小于栈顶元素时,node为最小值
: stkMin.push(stkMin[stkMin.length - 1]); //node大于栈顶元素时,栈顶元素为最小值 } function pop() { // write code here if (stk.length === 0) return null; stkMin.pop(); return stk.pop(); } function top() { // write code here return stk[stk.length - 1]; //返回栈顶元素 } function min() { // write code here return stkMin[stkMin.length - 1]; }
  • 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。

//思路

判断一个序列是不是栈的弹出序列,其实是判断将序列1压入栈时,栈顶元素是否可以形成序列2,栈顶元素有三种可能:
1.当前栈顶
2.弹出栈顶之后的新栈顶
3.继续压入新的栈顶
比较顺序:1,2,3,可以最多的弹出所有元素
借助一个辅助栈,依次把所有元素压入这个栈里,设置一个指针idx指向需要弹出的元素,初始指向弹出序列的第一个元素
每次压入之后,都比较idx元素和栈顶元素是否相等,如果相等,就弹出这个值,idx指向下一个,循环比较所有相等值全部弹出,直到两个值不等,不再弹出序列,继续压入
数组里所有元素都压栈完成以后,如果辅助栈还有没弹出的元素,就代表
不是弹出序列,如果栈空了,就代表是弹出序列。

function IsPopOrder(pushV, popV) {
  // write code here
  //任意空数组/数组长度不相等,不满足条件
  if (pushV.length === 0 || popV.length === 0 || popV.length !== pushV.length)
    return false;
  //单个数组,比较一个元素
  if (pushV.length === 1 && popV.length === 1) return pushV[0] === popV[0];
  let stk = []; //辅助栈
  let idx = 0; //指针,指向popV的第一个元素
  //将pushV压入辅助栈
  for (let i = 0; i < pushV.length; i++) {
    stk.push(pushV[i]);
    // stk空或者栈顶元素和popV指针的元素不相等,跳过循环,继续入栈
    // 栈顶元素和popV指针的元素相等时,循环比较栈顶元素和pop中指针指向的元素
    while (stk.length != 0 && stk[stk.length - 1] === popV[idx]) {
      stk.pop(); // 栈顶元素出栈
      idx++; //指针下移,继续比较
    }
  }
  return stk.length === 0; //所有popV中的元素都按顺序出栈,则是一个弹出序列
}
IsPopOrder([1, 2, 3, 4, 5], [4, 5, 3, 2, 1]);
IsPopOrder([1], [2]);

 

posted @ 2019-09-14 17:19  siyecaohhc  阅读(392)  评论(0编辑  收藏  举报