2

用两个栈实现队列

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

var stack1 = [];
var stack2 = [];
function push(node){
  stack1.push(node);
}
function pop(){
  if(stack2.length <= 0) {
    while(stack1.length > 0) {
      let data = stack1.pop();
      stack2.push(data);
    }
  }
  return stack2.pop();
}
push(1);
push(2);
push(3);
push(4);

console.log(pop());
console.log(pop());
console.log(pop());
console.log(pop());

用两个队列实现一个栈

const queue1 = []
const queue2 = []

function push(x) {
  if (queue1.length === 0) {
    queue1.push(x)

    while (queue2.length) {
      queue1.push(queue2.shift())
    }
  } else if (queue2.length === 0) {
    queue2.push(x)

    while (queue1.length) {
      queue2.push(queue1.shift())
    }
  }
};

function pop() {
  if (queue1.length !== 0) {
    return queue1.shift()
  } else {
    return queue2.shift()
  }
};

包含min函数的栈

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

思路:
1.定义两个栈,一个栈用于存储数据,另一个栈用于存储每次数据进栈时栈的最小值.
2.每次数据进栈时,将此数据和最小值栈的栈顶元素比较,将二者比较的较小值再次存入最小值栈.
4.数据栈出栈,最小值栈也出栈。
3.这样最小值栈的栈顶永远是当前栈的最小值。

var dataStack = [];
var minStack = [];
 
function push(node)
{
    dataStack.push(node);
    if(minStack.length === 0 ||  node < min()){
        minStack.push(node);
    }else{
        minStack.push(min());
    }
}
function pop()
{
    minStack.pop();
    return dataStack.pop();
}
function min()
{
    var length = minStack.length;
    return length>0&&minStack[length-1]
}

栈的压入、弹出序列

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

思路:
借用一个辅助栈,遍历压栈顺序,先将第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈。出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。

function IsPopOrder(pushV, popV) {
  if (!pushV || !popV || pushV.length == 0 || popV.length == 0) {
    return;
  }
  var stack = [];
  var idx = 0;
  for (var i = 0; i < pushV.length; i++) {
    stack.push(pushV[i]);
    while (stack.length && stack[stack.length - 1] == popV[idx]) {
      stack.pop();
      idx++;
    }
  }
  return stack.length == 0;
}

滑动窗口的最大值

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。 返回滑动窗口最大值。

思路:
借助一个辅助队列(双端队列),从头遍历数组,根据如下规则进行入队列或出队列操作: 

  1. 如果当前数字大于队列尾,则删除队列尾,直到当前数字小于等于队列尾,或者队列空,
  2. 当前数字入队列 
  3. 如果队列头超出滑动窗口范围,则删除队列头 

这样能始终保证队列头为当前的最大值

var maxSlidingWindow = function (nums, k) {
const window = [];
const result = [];
for (let i = 0; i < nums.length; i++) {
    // 1. 如果当前数字大于队列尾,则删除队列尾,直到当前数字小于等于队列尾,或者队列空,
    while(window.length>0 && nums[window[window.length-1]] <= nums[i]) {
        window.pop();
    }
    // 2. 当前数字入队列 
    window.push(i);
    // 3. 如果队列头超出滑动窗口范围,则删除队列头 
    if(window[0] <= i - k) {
        window.shift();
    }
    if(i + 1 >= k) {
        result.push(nums[window[0]]);
    }
}
return result;
};

console.log(maxSlidingWindow([1,3,-1,-3,5,3,6,7],3));
console.log(maxSlidingWindow([1,3,-1,-3,5,2,1,1],3));

鸡蛋炒番茄
1.1k 声望1.3k 粉丝

hello world