Jerry's Blog

Recording what I learned everyday

View on GitHub


23 October 2019

LeetCode(46) -- 993,

by Jerry Zhang

P993. Cousins in Binary Tree (Easy)

一个二叉树,根节点的深度为0。如果两个节点深度相同,但父节点不同,我们就叫它们cousin。

我的思路

先算出两个节点的深度,然后再判断它们的父节点是否相同。

我的代码

public class E_993_CousinsinBinaryTree {
    public boolean isCousins(TreeNode root, int x, int y) {
        int depthX = findDepth(root, 0, x);
        int depthY = findDepth(root, 0, y);
        return depthX == depthY && !sameParent(root, x, y);
    }

    private int findDepth(TreeNode node, int currentDepth, int target) {
        if (node.val == target) {
            return currentDepth;
        }
        if (node.left != null) {
            int depthLeft = findDepth(node.left, currentDepth + 1, target);
            if (depthLeft != -1) {
                return depthLeft;
            }
        }
        if (node.right != null) {
            int depthRight = findDepth(node.right, currentDepth + 1, target);
            if (depthRight != -1) {
                return depthRight;
            }
        }
        return -1;
    }

    private boolean sameParent(TreeNode root, int x, int y) {
        if (root == null) {
            return false;
        }
        if (root.left != null && root.right != null) {
            if ((root.left.val == x && root.right.val == y) ||
            (root.left.val == y && root.right.val == x)) {
                return true;
            }
        }
        return sameParent(root.left, x, y) || sameParent(root.right, x, y);
    }

    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.right = new TreeNode(2);
        root.right.left = new TreeNode(3);
        root.right.right = new TreeNode(5);
        root.right.left.left = new TreeNode(4);
        root.right.left.left.right = new TreeNode(6);
        boolean cousins = new E_993_CousinsinBinaryTree().isCousins(root, 5, 3);
        System.out.println("cousins = " + cousins);
    }
}

100%

最优解

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        if (root == null || x == y) {
            return false;
        }
        TreeNode xParent = new TreeNode(0), yParent = new TreeNode(0);
        int xLevel = getLevelOf(root, x, xParent);
        int yLevel = getLevelOf(root, y, yParent);
        return xLevel == yLevel && xParent.val != yParent.val;
    }

    private Integer getLevelOf(TreeNode node, int value, TreeNode parent) {
        if (node == null) {
            return null;
        }

        if (node.val == value) {
            return 0;
        }

        Integer left = getLevelOf(node.left, value, parent);
        if (left != null) {
            if (parent.val == 0) {
                parent.val = node.val;
            }
            return left + 1;
        }

        Integer right = getLevelOf(node.right, value, parent);
        if (right != null) {
            if (parent.val == 0) {
                parent.val = node.val;
            }
            return right + 1;
        }
        return null;
    }
}

P994. Rotting Oranges (Easy)

烂橘子问题:在一个矩阵中,2表示烂橘子,1表示好橘子,0表示该位置什么都没有。每过一天,所有烂橘子上下左右四个方向的好橘子也会烂掉。问经过几天之后,所有的橘子全烂掉?

我的思路

BFS,先全扫一遍,看看哪些橘子烂掉了,就把它们周边的好橘子的坐标放到一个list里。然后只要这个list不为空,就先把它们所有数变成2,再检查已经在list中的每一个坐标周边是否有好橘子,如果有,就重新放到list里。这里需要注意,遍历的次数,以初始的size为准,后来再加进去的,暂时先不管。(因为要计算天数,每一轮都是一天)

我的代码

public class E_994_RottingOranges {
    LinkedList<IntPair> list = new LinkedList<>();
    public int orangesRotting(int[][] grid) {
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == 2) {
                    checkAndAddToQueue(i, j, grid);
                }
            }
        }
        int count = 0;
        while (list.size() != 0) {
            count++;
            int size = list.size();
            for (IntPair pair : list) {
                grid[pair.x][pair.y] = 2;
            }
            for (int i = 0; i < size; i++) {
                IntPair pair = list.remove();
                checkAndAddToQueue(pair.x, pair.y, grid);
            }
        }
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == 1) {
                    return -1;
                }
            }
        }
        return count;
    }

    private void checkAndAddToQueue(int i, int j, int[][] grid) {
        if (i > 0 && grid[i - 1][j] == 1) {
            list.add(new IntPair(i - 1, j));
        }
        if (i < grid.length - 1 && grid[i + 1][j] == 1) {
            list.add(new IntPair(i + 1, j));
        }
        if (j > 0 && grid[i][j - 1] == 1) {
            list.add(new IntPair(i, j - 1));
        }
        if (j < grid[i].length - 1 && grid[i][j + 1] == 1) {
            list.add(new IntPair(i, j + 1));
        }
    }
}
 class IntPair {
    int x;
    int y;
    IntPair(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

86%

最优解

class Solution
{
  //private final static int EMPTY = 0;
  private final static int FRESH = 1;
  private final static int ROTTEN = 2;

  public int orangesRotting(int[][] grid)
  {
    final int n = grid.length;
    final int m = grid[0].length;

    int freshCount = 0;

    Queue<Integer> queue = new LinkedList<>();
    for (int i=0; i<n; i++)
      for (int j=0; j<m; j++)
      {
        if (grid[i][j] == FRESH)
          freshCount++;
        else if (grid[i][j] == ROTTEN)
          queue.add(i*m +j);
      }

    if (freshCount == 0) return 0;

    int minuts = 2;
    while (!queue.isEmpty())
    {
      int code = queue.remove();
      int i = code / m;
      int j = code % m;
      minuts = grid[i][j] + 1;
      int k = i-1;
      if ((k > -1) && (grid[k][j] == FRESH))
      {
        grid[k][j] = minuts;
        freshCount--;
        queue.add((k)*m +j);
      }

      k = i+1;
      if ((k < n) && (grid[k][j] == FRESH))
      {
        grid[k][j] = minuts;
        freshCount--;
        queue.add((k)*m +j);
      }

      k = j-1;
      if ((k > -1) && (grid[i][k] == FRESH))
      {
        grid[i][k] = minuts;
        freshCount--;
        queue.add((i)*m +k);
      }

      k = j+1;
      if ((k < m) && (grid[i][k] == FRESH))
      {
        grid[i][k] = minuts;
        freshCount--;
        queue.add((i)*m +k);
      }
    }

    return (freshCount > 0) ? -1 : minuts - 3;
  }
}

i * 列数 + j,就能算出矩阵里的序号,不需要像我一样再写一个pair的类来记录。 这个代码的意思是,因为本身这个矩阵里0,1,2都有其特殊含义了,但是作者又想用矩阵里的数来代表过了几分钟,于是就把minute初始化成2,最后再减3。

tags: LeetCode