剑指Offer 28-29

92 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

28、对称的二叉树

题目:实现一个函数,判断二叉树是否是对称的。

解题思路

简单思路从上向下遍历,使用栈每次入栈两个节点,出栈时也同时出栈两个节点,这两个节点的顺序需要对应,即左子树的左节点和右子树的右节点进行比对,而左子树的右节点和右子树的左节点进行比对。入栈时也需要对应入栈,可得代码如下:

public boolean isSymmetric(TreeNode root) {
    if(root==null) return true;
    if(root.left==null&&root.right==null) return true;
    if(root.left==null||root.right==null) return false;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root.right);
    stack.push(root.left);
    while(!stack.isEmpty()){
        TreeNode left = stack.pop();
        TreeNode right = stack.pop();
        if(left==null&&right==null) continue;
        if(left==null||right==null||left.val!=right.val) return false;
        stack.push(left.right);
        stack.push(right.left);
        stack.push(left.left);
        stack.push(right.right);
    }
    return true;
}

上述是使用栈实现的,实际上,我们只需要比较一棵树的左子树和右子树的对应关系是否满足条件即可得到最终答案,之后两颗子树的子节点再次进行递归就可以得到最终的结果,可得代码如下:

public boolean isSymmetric(TreeNode root) {
    return isSymmetric2(root, root);
}

public boolean isSymmetric(TreeNode left, TreeNode right) {
    if(left==null&&right==null) return true;
    if(left==null||right==null||left.val!=right.val) return false;
    return isSymmetric(left.right, right.left)&&isSymmetric(left.left, right.right);
}

29、顺时针打印矩阵

题目:输入一个矩阵,要求将此矩阵顺时针打印。

解题思路

本题可用直观的思路进行解答,对于一个矩阵,首先从左向右扫描,到达边界即从上向下扫描,之后从右向左以及最后从下向上。本题的难点主要在于上下左右边界的确定,何时结束扫描是所需关注的。我们可用使用四个变量来代表这四个边界,每次扫描完成都更新边界,如果超出边界则结束循环,可得代码如下:

public int[] spiralOrder(int[][] matrix) {
    int row = matrix.length;
    if (row == 0) {
        return new int[0];
    }
    int column = matrix[0].length;
    int[] res = new int[row * column];
    int cur = 0;
    int left = 0;
    int right = column-1;
    int top = 0;
    int bottom = row - 1;

    while(true){
        // 向右走
        for(int i=left;i<=right;i++){
            res[cur++] = matrix[top][i];
        }
        if(++top>bottom) break;

        // 向下走
        for(int i=top;i<=bottom;i++){
            res[cur++] = matrix[i][right];
        }
        if(--right<left) break;

        // 向左走
        for(int i=right;i>=left;i--){
            res[cur++] = matrix[bottom][i];
        }
        if(--bottom<top) break;

        // 向上走
        for(int i=bottom;i>=top;i--){
            res[cur++] = matrix[i][left];
        }
        if(++left>right) break;
    }
    return res;
}