文章目录
- 1. 单词拆分
- 题干:
- 算法原理:
- 1. 状态表示:
- 2. 状态转移方程
- 3. 初始化
- 4. 填表顺序
- 5. 返回值
 
- 代码:
 
- 2. 环绕字符串中唯一的子字符串
- 题干:
- 算法原理:
- 1. 状态表示:
- 2. 状态转移方程
- 3. 初始化
- 4. 填表顺序
- 5. 返回值
 
- 代码:
 
- 3. 计算布尔二叉树的值
- 题干:
- 算法原理:
- 代码:
 
- 4. 求根节点到叶节点数字之和
- 题干:
- 算法原理:
- 代码:
 
1. 单词拆分

 原题链接
题干:
字符串 s 和一个字符串列表 wordDict
 利用字典中出现的一个或多个单词拼接出 s 则返回 true
字典中的单词可以重复使用
算法原理:
1. 状态表示:
dp[i] 表示: [0, i] 区间内的字符串,能否被字典中的单词拼接而成
2. 状态转移方程

 
3. 初始化
- 辅助结点⾥⾯的值要「保证后续填表是正确的」
- 「下标的映射关系」
dp[0] = true
 s = ’ ’ + s
4. 填表顺序
从左往右
5. 返回值
dp[n]
代码:
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        //优化:将字典里面的单词存在哈希表里面
        Set<String> hash = new HashSet(wordDict);
        int n = s.length();
        boolean[] dp = new boolean[n + 1];
        dp[0] = true;
        s = " " + s;//处理下标的映射关系
        for(int i = 1; i <= n; i++) {
            for(int j = i; j >= 1; j--) {
                if(dp[j - 1] && hash.contains(s.substring(j, i + 1))) {
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n];
    }
}
2. 环绕字符串中唯一的子字符串

 原题链接
题干:
字符串 base 为一个 “abcdefghijklmnopqrstuvwxyz” 无限环绕的字符串
 
给一个字符串 s ,统计并返回 s 中有多少 不同非空子串 也在base 中出现
 
算法原理:
1. 状态表示:
dp[i] 表示:以 i 位置的元素为结尾的所有子串里面,有多少个在 base 中出现过
2. 状态转移方程

3. 初始化
将表里面的值都初始化为 1
4. 填表顺序
从左往右
5. 返回值
这⾥不能直接返回 dp 表里面的和,因为会有重复的结果。
在返回之前,我们需要先「去重」:
- 相同字符结尾的 dp 值,我们仅需保留「最大」的即可,其余 dp 值对应的子串都可以在最大的里面找到
- 可以创建⼀个大小为 26 的数组,统计所有字符结尾的最大 dp 值
最后返回「数组中所有元素的和」即可。
代码:
class Solution {
    public int findSubstringInWraproundString(String ss) {
        int n = ss.length();
        char[] s = ss.toCharArray();
        //1. 利用 dp 得到每一个位置为结尾的最长连续数组的长度
        int[] dp = new int[n];
        for(int i = 0; i < n; i++) {
            dp[i] = 1;
        }
        for(int i = 1; i < n; i++) {
            if(s[i - 1] + 1 == s[i] || (s[i - 1] == 'z' && s[i] == 'a')) {
                dp[i] += dp[i - 1];
            }
        }
        //2. 确定返回值
        int[] hash = new int[26];
        for(int i = 0; i < n; i++) {
            hash[s[i] - 'a'] = Math.max(hash[s[i] - 'a'], dp[i]);
        }
        //3. 返回结果
        int sum = 0;
        for(int x : hash) {
            sum += x;
        }
        return sum;
    }
}
3. 计算布尔二叉树的值

 
 原题链接
题干:
叶子节点 要么值为 0 要么值为 1 ,其中 0 表示 False ,1 表示 True 。
非叶子节点 要么值为 2 要么值为 3 ,其中 2 表示逻辑或 OR ,3 表示逻辑与 AND 。
 
算法原理:
利用递归解决问题
 
 
代码:
class Solution {
    public boolean evaluateTree(TreeNode root) {
        if(root.left == null) {
            return root.val == 0 ? false : true;
        }
        boolean left = evaluateTree(root.left);
        boolean right = evaluateTree(root.right);
        return root.val == 2 ? left | right : left & right;
    }
}
4. 求根节点到叶节点数字之和

 原题链接
题干:
给一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字
 每条从根节点到叶节点的路径都代表一个数字
例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123
 计算从根节点到叶节点生成的 所有数字之和 。
算法原理:
使用递归解决问题
 
- 函数头
 int dfs(TreeNode* root, int preSum)
- 函数体
 ① ② ③ ④
- 递归出口
 叶子结点
代码:
class Solution {
    public int sumNumbers(TreeNode root) {
        return dfs(root, 0);
    }
    public int dfs(TreeNode root, int preSum) {
        preSum = preSum * 10 + root.val;
        if(root.left == null && root.right == null) {
            return preSum;
        }
        int ret = 0;
        if(root.left != null) {
            ret += dfs(root.left, preSum);
        }
        if(root.right != null) {
            ret += dfs(root.right, preSum);
        }
        return ret;
    }
}



















