[路飞]化栈为队和棒球比赛

96 阅读3分钟

一.#### 03.04. 化栈为队 实现一个MyQueue类,该类用两个栈来实现一个队列。

示例:

MyQueue queue = new MyQueue();

queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回 1 queue.empty(); // 返回 false

解题思路: 栈的操作是先入后出,队列的操作是先入先出,如果将栈和队列都当做数组来看待的话,栈每次出栈就是pop()删除数组最后一位,而对列出队是需要删除数组第一位,所以化栈为队,可以将数组反过来,比如入栈的顺序是[1,2,3],到了arr2就是[3,2,1],然后删除最后一位虽然是栈的操作,但是却实现了队列的操作,具体实现是定义两个数组,数组arr实现栈的入栈操作,数组arr2实现出队的操作,当arr2为空的时候就将arr反向导入arr2保证出队列数据不乱,代码如下:

//定义两个数组
let arr,arr2;
var MyQueue = function() {
    arr = [];//栈新增操作
    arr2 = []; //队列删除操作
};

/**
 * Push element x to the back of queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
    //入栈入队操作
    arr.push(x);
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function() {
    //判断arr2是否为空,如果为空就将入栈的数组反向导入arr保证出队的顺序
    MyQueue.prototype.toUpdate();
    //先入先出
    return arr2.shift()
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function() {
    //判断arr2是否为空,如果为空就将入栈的数组反向导入arr保证出队的顺序
    MyQueue.prototype.toUpdate();
    //查看队手元素
    return arr2[0]
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
    //当两个数组都为空的时候就是空占空队列
    return arr2.length == 0 && arr.length == 0;
};
//更新出队队列
MyQueue.prototype.toUpdate = function() {
    if(arr2.length == 0) {
        while(arr.length > 0){
          arr2.push(arr.shift())
        }   
    }
};

二.#### 682. 棒球比赛 你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:

整数 x - 表示本回合新获得分数 x "+" - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。 "D" - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。 "C" - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。 请你返回记录中所有得分的总和。

**思路:**本题比较简单,就是根据数组符号来操作,可以定义一个空数组来记录得分,然后每次获得数组长度来操作数组,代码如下:

var calPoints = function(ops) {
    //定义一个数组记录等分
    let arr = [];
    //循环操作数组
    for(let i = 0; i < ops.length; i ++){
        //获取数组长度
        let leng = arr.length;
        //判断是那种操作
        switch(ops[i]){
            case '+' : 
               //根据数组获取最后两位数组进行相加就是本轮得分
               arr.push(arr[leng -1] + arr[leng - 2]);
               break; 
            case 'D' :
               //根据数组长度获得上一轮分数乘以2就是本轮得分
               arr.push(arr[leng -1] * 2);
               break;
            case 'C' :
               //删除上一轮得分
               arr.pop();
               break;
            default :
                //利用parseInt()将字符串数字转换成数字类型方便后面相加乘等操作
                arr.push(parseInt(ops[i]))  
        }
    }
    let sun = 0;
    //得分累计
    for(let i = 0; i < arr.length; i ++){
        sun += arr[i];
    }
    return sun;
};