Stack

作者: Wilbur_ | 来源:发表于2020-12-06 09:41 被阅读0次

    刷题最主要要理解思想,如何利用抽象的数据结构来解决这个问题。

    算法的本质就是你通过一系列的运算能够获得题目要求想要的答案,所以思考这一系列步骤是可以通过抽象的数据结构或者之前的pattern来完成的,而好记性不如烂笔头子,所以把这些思想记录下来还是非常有用的,之后可以时不时翻出来看一下。

    而算法的改进也是先通过最基础的本办法一点点改进过来的。所以不必懊恼自己没能一开始就想出最优解。

    stack 的问题也有很多种, 今天又复习了一下inorder successor和walls and gates,发现自己既是了解了思想之后在实际implementation的时候还是不能实现这个算法。就说明自己的工程能力还是很弱,需要练习。

    inorder successor 这道题我主要卡在了如何利用stack来实现自己的想法这上面,我一开始想的是直接push root 进stack然后便利到最左边,然后pop,这样就可以开始对比两个的数值了。(当前node和target的数值)

    但这样想有个问题,如果目标的node是在这棵树上最右边的地方,那么你如何找到它inorder successor?所以正确的方式是在while (!stack.isEmpty()) 这个循环里面再嵌套一个判断条件,这样你每次pop的时候就是前一个node的inorder successor,因为你stack push的顺序就是按照inorder 的顺序push的,pop的时候就等于pop了它inorder successor。

    看一下下面的代码可能更清晰一点,精髓就在于他在结尾的时候更新了inorder的value,这样你下一次循环pop的时候一定是它的inorder successor。

            int inorder = Integer.MAX_VALUE;
            ArrayDeque<TreeNode> stack = new ArrayDeque<>();
            while (!stack.isEmpty() || root != null) {
                // go to most left child node
                while (root != null) {
                    stack.push(root);
                    root = root.left;
                }
                root = stack.pop();
                if (inorder == p.val) {
                    return root;
                }
                inorder = root.val;
                root = root.right;
            }
            return null;
    

    walls and gates这道题我也是在实现的时候出了问题,其实思想就是BFS,没什么好说的,但是实现的时候就遇到麻烦了。

    自己以为用两个for loop循环,找到一个gates的时候把坐标加入队列,然后把周围空房间的坐标更新后也加入队列就行了。

    但是这样结果就是你的答案并不是最优解,就是说题目要求空房间的坐标应该是离最近的gate的距离,那么你这样2个for loop找到一个gate就加入队列的用法实际上不能保证每个空房间的值都是离最近的gate的距离,所以这样implement是有问题的。

    正确的做法应该是在两个for loop的时候先把所有的gate的坐标加入队列,然后while(!q.isEmpty()) 在把每个gate附近空房间的值更新并加入队列,这样你就保证了你会先把每个gate附近的空房间的值更新(因为用了队列这个数据结构),所以保证了能够满足题目的要求。

    下面是代码:

    class wallsAndGates {
        int[][] dir = new int[][] {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
        int INF = Integer.MAX_VALUE;
        public void wallsAndGates(int[][] rooms) {
            int m = rooms.length;
            if (m == 0) return;
            int n = rooms[0].length;
            Queue<int[]> q = new LinkedList<>();
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (rooms[i][j] == 0) {
                        q.add(new int[] {i, j});
                    }
                }
            }
            while (!q.isEmpty()) {
                int[] gate = q.poll();
                int pos_x = gate[0];
                int pos_y = gate[1];
                for (int k = 0; k < 4; k++) {
                    int x = pos_x + dir[k][0];
                    int y = pos_y + dir[k][1];
                    if (x < 0 || x > m - 1 || y < 0 || y > n - 1) {
                        continue;
                    } else {
                        if (rooms[x][y] == INF) {
                            rooms[x][y] = rooms[pos_x][pos_y] + 1;
                            q.add(new int[] {x, y});
                        }
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Stack

          本文链接:https://www.haomeiwen.com/subject/ojdgiktx.html