leetcode打卡-二叉树II

目录

106. 从中序与后序遍历序列构造二叉树

112. 路径总和

404. 左叶子之和

513. 找树左下角的值

530. 二叉搜索树的最小绝对差

235. 二叉搜索树的最近公共祖先

 98. 验证二叉搜索树

701. 二叉搜索树中的插入操作

700. 二叉搜索树中的搜索

108. 将有序数组转换为二叉搜索树

236. 二叉树的最近公共祖先

 501. 二叉搜索树中的众数

538. 把二叉搜索树转换为累加树

669. 修剪二叉搜索树

 450. 删除二叉搜索树中的节点

 257. 二叉树的所有路径

110. 平衡二叉树

617. 合并二叉树

 654. 最大二叉树


106. 从中序与后序遍历序列构造二叉树

leetcode题目链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal

leetcode AC记录:

思路:中序遍历是左中右,后序遍历是左右中,按照这个顺序后序数组的末尾为根,然后找到根在中序数组中的位置,将中序数组分为左右子树,递归循环这个过程即可。

代码如下:

public TreeNode buildTree(int[] inorder, int[] postorder) {
        return buildTree(inorder, postorder, 0, inorder.length-1, 0, postorder.length - 1);
    }

    public TreeNode buildTree(int[] inorder, int[] postorder, int inBegin, int inEnd, int postBegin, int postEnd) {
        if(inBegin > inEnd || postBegin > postEnd) {
            return null;
        }

        TreeNode root = new TreeNode();
        root.val = postorder[postEnd];
        int rootIndex = getRootIndex(inorder, root.val, inBegin, inEnd);
        root.left = buildTree(inorder, postorder, inBegin, rootIndex-1 , postBegin, postBegin + rootIndex - inBegin -1);
        root.right = buildTree(inorder, postorder, rootIndex + 1, inEnd , postBegin + rootIndex - inBegin, postEnd - 1);
        return root;
    }

    public int getRootIndex(int[] arr, int val, int begin, int end) {
        while(begin <= end) {
            if(arr[begin] == val) {
                return begin;
            }
            begin++;
        }
        return -1;
    }

112. 路径总和

leetcode题目链接:https://leetcode.cn/problems/path-sum

leetcode AC记录: 

思路:使用回溯和递归,将当前节点的累加和传递到子树中,如果碰到叶子节点,判断和是否为目标值,如果是返回并将结果递归到上层,层层递归最终返回。

代码如下:

 public boolean hasPathSum(TreeNode root, int targetSum) {
        return pathSum(root, 0, targetSum);
    }

    public boolean pathSum(TreeNode node, int currentSum, int targetSum) {
        if(node == null) {
            return false;
        }
        currentSum += node.val;
        if(node.left == null && node.right == null && currentSum == targetSum) {
            return true;
        }

        boolean flag = false;
        if(node.left != null) {
            flag = pathSum(node.left, currentSum, targetSum);
            if(flag == true) {
                return true;
            }
        }

        if(node.right != null) {
            flag = pathSum(node.right, currentSum, targetSum);
            if(flag == true) {
                return true;
            }
        }

        return flag;
    }

404. 左叶子之和

leetcode题目链接:https://leetcode.cn/problems/sum-of-left-leaves/

leetcode AC记录:

思路:使用递归方式前序遍历,返回条件为遇到左右子树为空,如果判断遇到了左叶子节点,则累加左叶子节点的值。

代码如下:

public int sumOfLeftLeaves(TreeNode root) {
        if(root == null) {
            return 0;
        }

        if(root.left == null && root.right == null) {
            return 0;
        }

        int leftSum = sumOfLeftLeaves(root.left);
        if(root.left != null && root.left.left == null && root.left.right == null)  {
            leftSum = root.left.val;
        }

        int rightSum = sumOfLeftLeaves(root.right);

        return leftSum + rightSum;
    }

513. 找树左下角的值

leetcode题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/

leetcode AC记录:

思路:层序遍历,找到最后一层第一个元素即可。

代码如下:

public int findBottomLeftValue(TreeNode root) {
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int res = root.val;
        while(!queue.isEmpty()) {
            int size = queue.size();
            int index = 0;
            while(index < size) {
                TreeNode node = queue.pollFirst();
                if(index == 0) {
                    res = node.val;
                }
                index++;

                if(node.left != null) {
                    queue.offer(node.left);
                }

                if(node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return res;
    }

530. 二叉搜索树的最小绝对差

leetcode题目链接:https://leetcode.cn/problems/minimum-absolute-difference-in-bst

leetcode AC记录:

思路:使用中序迭代法遍历二叉树,因为是二叉搜索树,所以中序遍历是有序的,只需要记录上一个节点的值,和当前节点做差和最小差值进行比较赋值即可。

代码如下:

public int getMinimumDifference(TreeNode root) {
        TreeNode cur = root;
        int minDiff = Integer.MAX_VALUE;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        while(!stack.empty() || cur != null) {
            if(cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                TreeNode node = stack.pop();
                if(pre != null && node != null) {
                    minDiff = Math.min(Math.abs(pre.val - node.val), minDiff);
                }
                pre = node;
                cur = node.right;
            }
        }
        return minDiff;
    }

235. 二叉搜索树的最近公共祖先

leetcode题目链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree

leetcode AC记录:

思路:利用二叉搜索树的特性,左子树比根小,右子树比根大,如果根的值大于p并且大于q,说明公共祖先在当前节点的左子树中,如果根的值小于p并且小于q,说明公共祖先在当前节点的右子树中。

代码如下:

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while(root != null) {
            if(root.val > p.val && root.val > q.val) {
                root = root.left;
            } else if(root.val < p.val && root.val < q.val) {
                root = root.right;
            } else {
                return root;
            }
        }
        return null;
    }

 98. 验证二叉搜索树

leetcode题目链接:https://leetcode.cn/problems/validate-binary-search-tree

leetcode AC记录:

思路:递归判断。注意一点,只需要判断当前节点是否符合大于给定上限,小于给定下限,如果是左节点,上限为根节点的值,如果是右节点,下限为根节点的值。

代码如下:

public boolean isValidBST(TreeNode root) {
       return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    public boolean isValidBST(TreeNode root, long begin, long end) {
        if(root == null) {
            return true;
        }

        if(root.val <= begin || root.val >= end) {
            return false;
        }

        return isValidBST(root.left, begin, (long)root.val) && isValidBST(root.right, root.val, end);
    }

701. 二叉搜索树中的插入操作

leetcode题目链接:https://leetcode.cn/problems/insert-into-a-binary-search-tree/

leetcode AC记录:

思路:通过二叉搜索树的特点确定插入的位置,确定后作为叶子节点插入。

代码如下:

public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) {
            return new TreeNode(val);
        }
        //确定插入的位置 true代表左 false代表右
        boolean flag = true;
        TreeNode res = root;
        TreeNode pre = root;
        while(root != null) {
            pre = root;
            if(root.val > val) {
                root = root.left;
                flag = true;
            } else if(root.val < val) {
                root = root.right;
                flag = false;
            } 
        }

        TreeNode node = new TreeNode(val);
        if(flag) {
            pre.left = node;
        } else {
            pre.right = node;
        }
        return res;
    }

700. 二叉搜索树中的搜索

 leetcode题目链接:https://leetcode.cn/problems/search-in-a-binary-search-tree/

leetcode AC记录:

思路:递归搜索。

代码如下:

 public TreeNode searchBST(TreeNode root, int val) {
        if(root == null) {
            return null;
        }
        if(root.val == val) {
                return root;
        } else if(root.val > val) {
                return searchBST(root.left, val);
        } else {
                return searchBST(root.right, val);
        }
    }

108. 将有序数组转换为二叉搜索树

leetcode题目链接:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree

leetcode AC记录:

思路:二叉搜索树为有序的树,左子树比根小,右子树比根大,所以每次取数组中间节点当作根,然后将数组根据根节点位置分为左右子树,递归这个过程直到数组下标不符合要求(或者左右子树为空)。

代码如下:

 public TreeNode sortedArrayToBST(int[] nums) {
        //取中间的作为根节点
        return buildTree(nums, 0, nums.length-1);
    }

    public TreeNode buildTree(int[] nums, int begin, int end) {
        if(begin < 0 || end >= nums.length || begin > end) {
            return null;
        }
        int mid = (end - begin) / 2 + begin;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = buildTree(nums, begin, mid - 1);
        root.right = buildTree(nums, mid + 1, end);

        return root;
    }

236. 二叉树的最近公共祖先

leetcode题目链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/

leetcode AC记录:

思路:这道题有点难,使用前序遍历,如果当前节点包含q或者p,返回当前节点,如果左右子树都不为空返回结果(题目中的前提是肯定会包含p和q)。

代码如下:

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == q || root == p || root == null) {
            return root;
        }

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        if(left != null && right != null) {
            return root;
        } else if(left == null && right != null) {
            return right;
        } else if(left != null && right == null) {
            return left;
        } else {
            return null;
        }
    }   

 501. 二叉搜索树中的众数

leetcode题目链接:https://leetcode.cn/problems/find-mode-in-binary-search-tree/

leetcode AC记录:

思路:使用迭代法中序遍历,那么遍历过程是一个有序的数组,记录出现元素最多的次数maxCount,如果当前的次数大于maxCount,清空结果数组,将当前节点值放入结果数组;如果当前节点值次数等于maxCount,将当前节点放入结果数组。

代码如下:

public int[] findMode(TreeNode root) {
        List<Integer> list = new ArrayList<>(16);
        int maxCount = 0;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        Integer preval = null;
        int curCount = 1;
        while(!stack.empty() || cur != null) {
            if(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }else {
                TreeNode node = stack.pop();
                if(preval == null) {
                    curCount = 1;
                }else if(node.val == preval) {
                    curCount++;
                } else {
                    curCount = 1;
                }

                if(maxCount < curCount) {
                    maxCount = curCount;
                    list.clear();
                    list.add(node.val);
                } else if(maxCount == curCount){
                    list.add(node.val);
                }

                preval = node.val;
                cur = node.right;
            }
        }

        return list.stream().mapToInt(Integer::valueOf).toArray();
    }

538. 把二叉搜索树转换为累加树

leetcode题目链接:https://leetcode.cn/problems/convert-bst-to-greater-tree/ 

leetcode AC记录:

思路:使用迭代法中序遍历,区别在于先遍历右节点,即右中左,遍历节点累加赋值即可。

代码如下:

public TreeNode convertBST(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        int sum = 0;
        while(!stack.empty() || cur != null) {
            if(cur != null) {
                stack.push(cur);
                cur = cur.right;
            }else {
                TreeNode node = stack.pop();
                sum += node.val;
                node.val = sum;
                cur = node.left;
            }
        }
        return root;
    }

669. 修剪二叉搜索树

leetcode题目链接:https://leetcode.cn/problems/trim-a-binary-search-tree/ 

leetcode AC记录:

思路:如果当前节点值在范围里,递归处理左右子树;如果当前节点值小于下限,根据二叉搜索树的特点,说明当前节点的左子树也不符合条件,返回当前节点的右子树并递归处理,当前节点大于上限同理处理。

代码如下:

 public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null) {
            return null;
        } else if(root.val >= low && root.val <= high) {
            root.left = trimBST(root.left, low, high);
            root.right = trimBST(root.right, low, high);
        } else if(root.val < low){
            return trimBST(root.right, low, high);
        } else if(root.val > high) {
            return trimBST(root.left, low, high);
        }

        return root;
    }

 450. 删除二叉搜索树中的节点

leetcode题目链接:https://leetcode.cn/problems/delete-node-in-a-bst/

leetcode AC记录:

思路:删除二叉搜索树的节点相对于增加节点难很多,删除后需要调整树的结构。难点在于递归的处理细节,刚开始写的时候我会想如果删除的是根节点该如何处理,其实出发点不对,只需要考虑当前节点该如何操作就行:如果当前节点大于key,递归删除左节点;如果当前节点小于key,递归删除右节点;如果当前节点等于key,需要删除当前节点。下面讨论下如何删除当前节点:

        如果当前节点的左右子树为空,说明删除的是叶子节点,直接返回空;

        如果当前节点的左右子树其中一个为空,返回不为空的;

        如果当前节点的左右子树都不为空,把右子树当作根,左子树应该放到右子树的最左的叶子节点处。

代码如下:

public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null) {
            return null;
        }else if(root.val > key) {
            root.left = deleteNode(root.left, key);
        } else if(root.val < key) {
            root.right = deleteNode(root.right, key);
        } else {
            if(root.left == null) {
                return root.right;
            } else if(root.right == null) {
                return root.left;
            } else {
                TreeNode res = root.right;
                TreeNode left = root.left;
                TreeNode right = root.right;
                while(right.left != null) {
                    right = right.left;
                }
                right.left = left;
                return res;
            }
        }

        return root;
    }

 257. 二叉树的所有路径

leetcode题目链接:https://leetcode.cn/problems/binary-tree-paths

leetcode AC记录:

思路:回溯和递归,递归用来遍历二叉树,回溯用来回退节点。

代码如下:

public List<String> binaryTreePaths(TreeNode root) {
        List<Integer> list = new ArrayList<>(16);
        List<String> res = new ArrayList<>(16);
        traversal(root, list, res);
        return res;
    }


    public void traversal(TreeNode node, List<Integer> path, List<String> res) {

        if(node == null) {
            return;            
        }

        path.add(node.val);
        if(node.left == null && node.right == null) {
            res.add(path.stream().map(String::valueOf).collect(Collectors.joining("->")));
            return;
        }

        if(node.left != null) {
            traversal(node.left, path, res);
            path.remove(path.size()-1);
        }

        if(node.right != null) {
            traversal(node.right, path, res);
            path.remove(path.size()-1);
        }
    }

110. 平衡二叉树

leetcode题目链接:https://leetcode.cn/problems/balanced-binary-tree

leetcode AC记录:

思路:使用后序递归遍历二叉树,返回条件为遇到空节点高度为0。分别判断左右子树的高度,高度是从叶子节点开始累加计算,如果高度差不符合要求返回-1。

代码如下:

public boolean isBalanced(TreeNode root) {
        return high(root) != -1;
    }

    public int high(TreeNode node) {
        if(node == null) return 0;

        int leftHeight = high(node.left);
        int rightHeight = high(node.right);
        
        if(leftHeight == -1 || rightHeight == -1) {
            return -1;
        }

        int abs = Math.abs(leftHeight - rightHeight);
        if(abs > 1) {
            return -1;
        }

        return Math.max(leftHeight, rightHeight) + 1;
    }

617. 合并二叉树

leetcode题目链接:https://leetcode.cn/problems/merge-two-binary-trees/

leetcode AC记录:

思路:递归合并,如果树1为空,返回树2;如果树2为空,返回树1;如果都不为空,树1的节点值累加树2的值,最后返回树1的根。

代码如下:

public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null && root2 == null) {
            return null;
        } else if(root1 == null && root2 != null) {
            return root2;
        } else if(root1 != null && root2 == null) {
            return root1;
        }

        if(root1 != null && root2 != null) {
            root1.val += root2.val;
            root1.left = mergeTrees(root1.left, root2.left);
            root1.right = mergeTrees(root1.right, root2.right);
        }

        return root1;
    }

 654. 最大二叉树

leetcode题目链接:https://leetcode.cn/problems/maximum-binary-tree/

leetcode AC记录:

思路:递归,和使用数组构建二叉搜索树类似。

代码如下:

public TreeNode constructMaximumBinaryTree(int[] nums) {
        return construct(nums, 0, nums.length-1);
    }

    public TreeNode construct(int[] nums, int beginIndex, int endIndex) {
        if(beginIndex < 0 || endIndex >= nums.length || beginIndex > endIndex) {
            return null;
        }
        int maxIndex = maxIndex(nums, beginIndex, endIndex);
        TreeNode root = new TreeNode(nums[maxIndex]);
        root.left = construct(nums, beginIndex, maxIndex-1);
        root.right = construct(nums, maxIndex+1, endIndex);
        return root;
    }

    public int maxIndex(int[] nums, int beginIndex, int endIndex) {
        int index = beginIndex;
        while(++beginIndex <= endIndex) {
            if(nums[index] < nums[beginIndex]) {
                index = beginIndex;
            }
        }
        return index;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值