以下思路来自代码随想录和官方题解。
70.爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
4. 1 阶 + 1 阶 + 1 阶
5. 1 阶 + 2 阶
6. 2 阶 + 1 阶
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
118.杨辉三角
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
输入: numRows = 1
输出: [[1]]
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> row1 = new ArrayList<>();
row1.add(1); // 第一行只有一个元素,值为1
result.add(row1);
if (numRows == 1) { // 如果只需要生成一行,直接返回结果
return result;
}
List<Integer> row2 = new ArrayList<>();
row2.add(1); // 第二行的第一个元素为1
row2.add(1); // 第二个元素也为1
result.add(row2); // 将第二行添加到结果中
if (numRows == 2) { // 如果只需要生成两行,直接返回结果
return result;
}
// 从第三行开始生成
for (int i = 2; i < numRows; i++) {
List<Integer> list = new ArrayList<>();
// 当前行的第一个元素为1
list.add(1);
for (int j = 1; j < i; j++) {
// 计算当前行的中间元素,等于上一行的左上方元素与上方元素的和
Integer temp = result.get(i - 1).get(j - 1) + result.get(i - 1).get(j);
list.add(temp);
}
// 当前行的最后一个元素为1
list.add(1);
result.add(list);
}
return result;
}
}
279.完全平方数
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
输入:n = 13
输出:2
解释:13 = 4 + 9
class Solution {
public int numSquares(int n) {
int[] f = new int[n + 1];
for (int i = 1; i <= n; i++) { // 遍历 1 到 n
int minn = Integer.MAX_VALUE; // 初始化 minn 为最大整数值
for (int j = 1; j * j <= i; j++) { // 遍历 1 到 i 的平方根
minn = Math.min(minn, f[i - j * j]); // 更新 minn 为 f[i - j * j] 和 minn 中的较小值
}
// 将 f[i] 设置为 minn + 1
f[i] = minn + 1;
}
return f[n];
}
}
139.单词拆分
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
注意,你可以重复使用字典中的单词。
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
Set<String> set = new HashSet<>(wordDict);
boolean[] dp = new boolean[s.length()+1];
// 初始化dp[0]为true,表示空字符串可以由空单词组成
dp[0] = true;
for(int i=1;i<=s.length();i++){
for(int j=0;j<i;j++){
// 如果dp[j]为true且s的子串s.substring(j,i)在wordDict中
if(dp[j] && set.contains(s.substring(j,i))){
// 将dp[i]设置为true,表示s的前i个字符可以由wordDict中的单词组成
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
}
647.回文子串
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
//获取字符串s的长度n,并初始化答案ans为0。
//使用一个for循环遍历所有可能的回文中心位置,范围是0到2 * n - 1。
//对于每个中心位置i,计算左右边界l和r。如果i是偶数,则l = i / 2,r = l + 1;如果i是奇数,则l = i / 2,r = l。
//使用while循环检查当前中心位置是否为回文子串的中心。如果l >= 0且r < n且s.charAt(l) == s.charAt(r),则说明当前中心位置是回文子串的中心。
//如果当前中心位置是回文子串的中心,将左边界l减1,右边界r加1,并将答案ans加1。
//当for循环结束后,返回答案ans。
class Solution {
public int countSubstrings(String s) {
int n = s.length(), ans = 0;
for (int i = 0; i < 2 * n - 1; ++i) {
int l = i / 2, r = i / 2 + i % 2;
while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) {
--l;
++r;
++ans;
}
}
return ans;
}
}