Skip to content

Latest commit

 

History

History
350 lines (306 loc) · 9.03 KB

File metadata and controls

350 lines (306 loc) · 9.03 KB

栈和队列

简介

的特点是后入先出,根据这个特点可以临时保存一些数据,之后用到依次再弹出来,常用于 DFS 深度搜索

队列一般常用于 BFS 广度搜索,类似一层一层的搜索。

Stack 栈

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

思路:用两个栈实现,一个最小栈始终保证最小值在顶部

/**
 * initialize your data structure here.
 */
var MinStack = function() {
    this.stack = []; // JS用数组表示栈
    this.minStack = [Infinity];
};

/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    this.stack.push(x);
    this.minStack.push(Math.min(this.minStack[this.minStack.length-1],x));
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    this.stack.pop();
    this.minStack.pop();
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    return this.stack[this.stack.length-1];
};

/**
 * @return {number}
 */
MinStack.prototype.getMin = function() {
    return this.minStack[this.minStack.length-1];
};
var evalRPN = function (tokens) {
    const stack = []
    for (const item of tokens) {
        if (!isNaN(+item)) {
            stack.push(item)
        } else {
            let res = 0
            const top = parseInt(stack.pop()) //在栈中的位置靠上(被除数)
            const down = parseInt(stack.pop()) //靠下(除数)
            switch (item) {
                case '+':
                    res = top + down
                    break
                case '-':
                    res = down - top
                    break
                case '*':
                    res = top * down
                    break
                case '/':
                    res = parseInt(down / top)
                    break
            }
            stack.push(res)
        }
    }
    return stack[0]
};

给定一个经过编码的字符串,返回它解码后的字符串。

输入:s = "3[a]2[bc]" 输出:"aaabcbc"

var decodeString = function (s) {
    const stack = []
    for (let i = 0; i < s.length; i++) {
        const char = s[i]
        if (char !== ']') {
            stack.push(char)
        } else {
            let str = ''
            while (stack.length > 0) {
                const temp = stack.pop()
                if (temp !== '[') {
                    str = temp + str
                } else {
                    let num = ''
                    while (stack.length > 0) {
                        const tempNum = stack.pop() // 处理类似100的数字,此时栈中['1','0','0']
                        if (!isNaN(tempNum)) {
                            num = tempNum + num
                        } else {
                            stack.push(tempNum)
                            break
                        }
                    }
                    str = str.repeat(+num)
                    break
                }
            }
            stack.push(str)
        }
    }
    return stack.join('')
}
var inorderTraversal = function (root) { //递归
    if (root === null) {
        return []
    }
    const res = [];
    (function inOrder(root) {
        if (!root) {
            return
        }
        inOrder(root.left)
        res.push(root.val)
        inOrder(root.right)
    })(root);
    return res
};
var inorderTraversal = function (root) {
    const stack = []
    const res = []
    let current = root
    while (stack.length > 0 || current) {
        while (current) {
            stack.push(current)
            current = current.left
        }
        current = stack.pop()
        res.push(current.val)
        current = current.right
    }
    return res
};

给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。

var cloneGraph = function (node) {
    let visited = new Map();
    return  (function clone(node, visited) {
        if (!node) {
            return null
        }
        if (visited.has(node)) {
            return visited.get(node)
        }
        const newNode = new Node(node.val)
        visited.set(node, newNode)
        for (let i = 0; i < node.neighbors.length; i++) {
            newNode.neighbors[i] = clone(node.neighbors[i], visited)
        }
        return newNode
    })(node, visited)
};

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

var numIslands = function (grid) {
    const nr = grid.length
    const nc = grid[0].length
    let resNum = 0
    for (let i = 0; i < nr; i++) {
        for (let j = 0; j < nc; j++) {
            if (grid[i][j] === '1') {
                resNum++
                dfs(grid, i, j)
            }
        }
    }
    return resNum
};

const dfs = (grid, row, col) => {
    const gr = grid.length
    const gc = grid[0].length
    if (row < 0 || col < 0 || row >= gr || col >= gc || grid[row][col] === '0') {
        return 0
    }
    grid[row][col] = '0'
    dfs(grid, row + 1, col)
    dfs(grid, row - 1, col)
    dfs(grid, row, col + 1)
    dfs(grid, row, col - 1)
}

84. 柱状图中最大的矩形

Queue 队列

/**
 * Initialize your data structure here.
 */
var MyQueue = function () {
    this.stack1 = []
    this.stack2 = []
};

/**
 * Push element x to the back of queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function (x) {
    this.stack1.push(x)
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function () {
    if (this.stack2.length > 0) {
        return this.stack2.pop()
    } else {
        while (this.stack1.length > 0) {
            this.stack2.push(this.stack1.pop())
        }
        return this.stack2.pop()
    }
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function () {
    if (this.stack2.length > 0) {
        return this.stack2[this.stack2.length - 1]
    } else {
        while (this.stack1.length > 0) {
            this.stack2.push(this.stack1.pop())
        }
        return this.stack2[this.stack2.length - 1]
    }
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function () {
    if (this.stack1.length === 0 && this.stack2.length === 0) {
        return true
    }
    return false
};
var updateMatrix = function (matrix) {
    const dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    const m = matrix.length, n = matrix[0].length
    const dist = new Array(m).fill(new Array(n).fill(0))
    const seen = new Array(m).fill(new Array(n).fill(false))
    const queue = []
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (matrix[i][j] === 0) {
                queue.push([i, j])
                seen[i][j] = true
            }
        }
    }
    while (queue.length > 0) {
        const [i, j] = queue.shift()
        for (let d = 0; d < 4; d++) {
            const ni = i + dirs[d][0]
            const nj = j + dirs[d][1]
            if (ni >= 0 && ni < m && nj >= 0 && nj < n && !seen[ni][nj]) {
                dist[ni][nj] = dist[i][j] + 1
                queue.push([ni, nj])
                seen[ni][nj] = true
            }
        }
    }
    return dist
};

总结

  • 熟悉栈的使用场景
    • 后入先出,保存临时值
    • 利用栈 DFS 深度搜索
  • 熟悉队列的使用场景
    • 利用队列 BFS 广度搜索

练习