剑指offer-DFS

剑指 Offer 13. 机器人的运动范围 - 力扣(LeetCode) (leetcode-cn.com)

  • 思路:

    1. 和hot100的62类似,但是注意本题的条件,既然说了是dfs,那么必然可以使用dfs的方法进行解决。
    2. 注意题目条件:它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。这个就是不合法的返回。
    3. 设置一个访问数组就好。
  • 代码:

    class Solution {
        public int movingCount(int m, int n, int k) {
            //数位之和不能大于k
            boolean[][] visited = new boolean[m][n];
            return dfs(m, n, 0, 0, visited, k);
        }
        //x,y表示现在的位置
        public int dfs(int m, int n, int x, int y, boolean[][] visited, int k){
            if(x < 0 || y < 0 || x >= m || y >= n || visited[x][y] || x/10+x%10+y/10+y%10 > k){
                return 0;
            }
            visited[x][y] = true;
            return 1 + dfs(m, n, x + 1, y, visited, k) + dfs(m, n, x, y + 1, visited, k);
        }
    }
    

剑指 Offer 26. 树的子结构 - 力扣(LeetCode) (leetcode-cn.com)

  • 思考:仔细思考本题的做法。

    1. 在树A中找到树B的根节点值R。
    2. 判断树A以R为根节点的子树是不是包含和树B一样的结构。
  • 代码:

    class Solution {
        public boolean isSubStructure(TreeNode A, TreeNode B) {
            //因为可能不一定从根开始,所以该函数也得递归。所以设置递归出口。
            if(A == null || B == null){
                return false;
            }
            //可能是从根开始,也有可能从A的左子树或者A的右子树
            return dfs(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
        }
        private boolean dfs(TreeNode A, TreeNode B){
            //当dfs的时候,如果b是空的话,那么就意味着B已经走完了,不管此事A的情况如何,B肯定是A的子树
            if(B == null){
                return true;
            }
            //只要A为空或者值不等,那么就不是,因为A的结构肯定是大于等于B的结构,一旦A先为空,而B还有,那么肯定就是错的。
            if(A == null || A.val != B.val){
                return false;
            }
            //接着两个树的左左和右右都判断。
            return dfs(A.left, B.left) && dfs(A.right, B.right);
        }
    }
    

剑指 Offer 27. 二叉树的镜像 - 力扣(LeetCode) (leetcode-cn.com)

  • 思路:因为题目本身就是一个子问题,那么直接无限递归下去,设置递归出口,记录左右树,然后根节点的右连接左,左连接右。

  • 代码:

    class Solution {
        public TreeNode mirrorTree(TreeNode root) {
            if(root == null){
                return null;
            }
            TreeNode left = mirrorTree(root.left);
            TreeNode right = mirrorTree(root.right);
            root.left = right;
            root.right = left;
            return root;
        }
    }
    

剑指 Offer 28. 对称的二叉树 - 力扣(LeetCode) (leetcode-cn.com)

  • 思路:左右子树拆开,分别进行对比。

  • 代码:

    class Solution {
        public boolean isSymmetric(TreeNode root) {
            if(root == null){
                return true;
            }
            return dfs(root.left, root.right);
        }
        public boolean dfs(TreeNode root1, TreeNode root2){
            if(root1 == null && root2 == null){
                return true;
            }
            if(root1 == null || root2 == null){
                return false;
            }
            return root1.val == root2.val && dfs(root1.left, root2.right) && dfs(root1.right, root2.left);
        }
    }
    

剑指 Offer 37. 序列化二叉树 - 力扣(LeetCode) (leetcode-cn.com)

  • 思路:

    1. 使用先序遍历完成序列化的操作。
      1. 示例给出的:1,2,null,null,3,4,null,null,5,null,null。
    2. 反序列化:先把给定的数组使用","隔开,这样得到只有数字或者null的字符串,构造成一个list<string>,传入buildTree中。
      1. 在buildTree中,如果当前的list集合中,第一个就是null,说明是个空树,这里的空树也可能是叶子结点的子结点,那么从list中删除,再返回一个空,直接返回就说明不管是空树还是叶子结点,都不会再向左或者右走了。如果是叶子结点的子结点,那么左右两端都是空,那么这里直接返回null那么就不再判断另外一边了。
      2. 不满足的话,创建一个根节点,节点值就是list集合第一个元素值。完成了根节点的创建之后要将该元素移除。
      3. 根据先序遍历,根左右,那么根取值完成之后,接下来就是判断右子树的操作。其left和right分别调用BuildTree就可以完成一个树的构建。
      4. 返回这棵树。
  • 代码:

    public class Codec {
    
        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
            if(root == null){
                return "null,";
            }
            String leftSerialize = serialize(root.left);
            String rightSerialize = serialize(root.right);
            return root.val + "," + leftSerialize + rightSerialize;
        }
    
        // Decodes your encoded data to tree.
        public TreeNode deserialize(String data) {
            String[] temp = data.split(",");
            List<String> tempList = new LinkedList<>(Arrays.asList(temp));
            return buildTree(tempList);
        }
        public TreeNode buildTree(List<String> tempList){
            if(tempList.get(0).equals("null")){
                tempList.remove(0);
                return null;
            }
            TreeNode root = new TreeNode(Integer.valueOf(tempList.get(0)));
            tempList.remove(0);
            root.left = buildTree(tempList);
            root.right = buildTree(tempList);
            return root;
        }
    }
    

剑指 Offer 55 - I. 二叉树的深度 - 力扣(LeetCode) (leetcode-cn.com)

  • 思路:记住最后要加根节点才是最后的总高度。

  • 代码:

    class Solution {
        public int maxDepth(TreeNode root) {
            if(root == null){
                return 0;
            }
            int left = maxDepth(root.left);
            int right = maxDepth(root.right);
            return Math.max(left, right) + 1;
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值