1022. 从根到叶的二进制数之和 / 剑指 Offer II 066. 单词之和

1022. 从根到叶的二进制数之和【简单题】【每日一题】

思路:

前序遍历二叉树,遇到叶子节点时,将从根节点到叶子节点的路径组成的二进制数转为十进制累加进ans,最后返回ans即可。二叉树的遍历有两种方式,一种是递归遍历,一种是迭代遍历。

【递归法】

进入递归函数之后,如果当前节点root = null,返回0。如果当前节点不为空,则将传入值左移一位之后加上当前节点的值,用于表示当前路径的二进制数。
如果当前节点是叶子节点,那么路径走到终点,递归函数返回当前路径的值。
如果当前节点不是叶子节点,那么递归调用递归函数,传入当前节点的左子节点和当前二进制数,传入当前节点的右子节点和当前二进制数,递归函数最终返回两个递归结果之和。

【迭代法】

使用栈来模拟递归,同时使用prev指针记录上一个访问过的指针 当root不为空 或者 栈不为空 进入while循环:
首先不断向左遍历二叉树,将遇到的节点入栈,并更新根节点到当前节点的路径形成的二进制数 用val 表示;
root为栈顶元素,此时root的左子树肯定是全部访问过的, 如果此时root的右子节点为null或者右子节点为 prev
说明root的左子树和右子树全部访问完毕,那么此时,如果 root 为叶子节点,那么将当前的val 累加进ans,然后将val右移1位,令二进制搜索回退,栈顶元素弹出表示当前节点遍历完毕,将root赋给prev标记上一个访问过的节点,令rootnull尝试对此时栈顶元素进行判断||
如果此时root的右子树尚未全部访问完毕,则将root更新为root的右子节点,遍历 root的右子树。

代码:

【递归】

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    public int sumRootToLeaf(TreeNode root) {
        return dfs(root,0);
    }

    public int dfs(TreeNode root,int cur){
        //如果为 null 返回0
        if (root == null){
            return 0;
        }
        //将传入值左移一位 并加上当前节点的值,表示二叉树遍历到当前节点时其路径所表示的二进制数
        cur = (cur << 1) | root.val;
        //如果当前节点为叶子节点 即没有左子节点和右子节点 ,返回遍历到当前叶子节点时的二进制数
        if (root.left == null && root.right == null){
            return cur;
        }
        //如果不为叶子节点 则返回其左子节点代表的二进制数与右子节点代表的二进制数之和
        return dfs(root.left,cur) + dfs(root.right,cur);
    }
}

【迭代】

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    public int sumRootToLeaf(TreeNode root) {
        Deque<TreeNode> nodes = new ArrayDeque<>();
        int val = 0, ans = 0;
        TreeNode prev = null;
        while (root != null || !nodes.isEmpty()){
            //向左遍历二叉树,遍历过程中将遇到的所有节点压入栈,并将 val 值不断左移1位并累加当前节点值
            while (root != null){
                val = (val << 1) | root.val;
                nodes.push(root);
                root = root.left;
            }
            //此时栈顶元素即为二叉树未遍历到的节点中 最左侧的节点,将其赋给 root
            root = nodes.peek();
            //如果 root 的右子节点 为 null 或者 root 的右子节点 与 前置节点 相同,说明节点 root 的左子树和右子树都已经访问过了
            if (root.right == null || root.right == prev){
                //如果 root 的左子节点为 null 且 root 的右子节点 也为 null 说明遇到叶子节点,ans 累加 val
                if (root.left == null && root.right == null){
                    ans += val;
                }
                //val 右移1位 表示二进制搜索回退
                val >>= 1;
                // nodes栈顶弹出 表示当前栈顶节点 root 已结束遍历
                nodes.pop();
                //将 root 赋给 prev ,标记 最后一次访问过的节点
                prev = root;
                //将 root 置为 null
                root = null;
            }else {
                //右子树未被访问过 将 root 的右子节点赋给 root 遍历 root 的右子树
                root = root.right;
            }
        }
        return ans;
    }
}

剑指 Offer II 066. 单词之和【中等题】

思路:

我偏不用字典树,就用暴力遍历!

代码:

class MapSum {

    Map<String,Integer> map;
    /** Initialize your data structure here. */
    public MapSum() {
        this.map = new HashMap<>();
    }
    
    public void insert(String key, int val) {
        map.put(key,val);
    }
    
    public int sum(String prefix) {
        int n1 = prefix.length();
        int ans = 0;
        Set<String> set = map.keySet();
        for (String s : set) {
            int n2 = s.length();
            if (n1 <= n2 && prefix.equals(s.substring(0,n1))){
                ans += map.get(s);
            }
        }
        return ans;
    }
}

/**
 * Your MapSum object will be instantiated and called as such:
 * MapSum obj = new MapSum();
 * obj.insert(key,val);
 * int param_2 = obj.sum(prefix);
 */

你可能感兴趣的:(力扣刷题记录,数据结构,leetcode,算法,java,刷题记录)