@[toc]
一、I. 斐波那契数列
public int fib(int n) {
int a = 0, b = 1, sum;
for(int i = 0; i < n; i++){
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return a;
}
二、II. 青蛙跳台阶问题
public int numWays(int n) {
if (n == 0 || n == 1) {
return 1;
}
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i < dp.length; i++) {
dp[i] = (dp[i - 1] + dp[i - 2]) % 1000000007;
}
return dp[n];
}
三、正则表达式匹配
public boolean isMatch(String s, String p) {
int m = s.length() + 1, n = p.length() + 1;
boolean[][] dp = new boolean[m][n];
dp[0][0] = true;
for(int j = 2; j < n; j += 2) {
dp[0][j] = dp[0][j - 2] && p.charAt(j - 1) == '*';
}
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
dp[i][j] = p.charAt(j - 1) == '*' ?
dp[i][j - 2] || dp[i - 1][j] && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.') :
dp[i - 1][j - 1] && (p.charAt(j - 1) == '.' || s.charAt(i - 1) == p.charAt(j - 1));
}
}
return dp[m - 1][n - 1];
}
四、连续子数组的最大和
public int maxSubArray(int[] nums) {
if (nums.length == 1) {
return nums[0];
} else {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < dp.length; i++) {
dp[i] = dp[i - 1] > 0 ? dp[i - 1] + nums[i] : nums[i];
max = Math.max(dp[i],max);
}
return max;
}
}
五、把数字翻译成字符串
public int translateNum(int num) {
if (num < 10) {
return 1;
}
String str = String.valueOf(num);
int[] dp = new int[str.length()];
dp[0] = 1;
for (int i = 1; i < dp.length; i++) {
int n = Integer.parseInt(str.substring(i - 1, i + 1));
if (n <= 25 && str.charAt(i - 1) != '0') {
if (i > 1) {
dp[i] = dp[i - 1] + dp[i - 2];
} else {
dp[i] = dp[i - 1] + 1;
}
} else {
dp[i] = dp[i - 1];
}
}
return dp[str.length() - 1];
}
六、礼物的最大价值
public int maxValue(int[][] grid) {
int[][] dp = new int[grid.length][grid[0].length];
dp[0][0] = grid[0][0];
// 初始化第一行
for (int i = 1; i < dp[0].length; i++) {
dp[0][i] = grid[0][i] + dp[0][i - 1];
}
// 初始化第一列
for (int i = 1; i < dp.length; i++) {
dp[i][0] = grid[i][0] + dp[i - 1][0];
}
// 开始dp
for (int i = 1; i < dp.length; i++) {
for (int j = 1; j < dp[0].length; j++) {
dp[i][j] = grid[i][j] + Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[dp.length - 1][dp[0].length - 1];
}
七、最长不含重复字符的子字符串
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> map = new HashMap<>();
int res = 0, tmp = 0, len = s.length();
for(int j = 0; j < len; j++) {
// 获取索引 i
int i = map.getOrDefault(s.charAt(j), -1);
// 更新哈希表
map.put(s.charAt(j), j);
// dp[j - 1] -> dp[j]
tmp = tmp < j - i ? tmp + 1 : j - i;
// max(dp[j - 1], dp[j])
res = Math.max(res, tmp);
}
return res;
}
八、丑数
public int nthUglyNumber(int n) {
int a = 0, b = 0, c = 0;
int[] dp = new int[n];
dp[0] = 1;
for(int i = 1; i < n; i++) {
int n2 = dp[a] * 2, n3 = dp[b] * 3, n5 = dp[c] * 5;
dp[i] = Math.min(Math.min(n2, n3), n5);
if(dp[i] == n2) {
a++;
}
if(dp[i] == n3) {
b++;
}
if(dp[i] == n5) {
c++;
}
}
return dp[n - 1];
}
九、n 个骰子的点数
public double[] dicesProbability(int n) {
double[] dp = new double[6];
Arrays.fill(dp, 1.0 / 6.0);
for (int i = 2; i <= n; i++) {
double[] tmp = new double[5 * i + 1];
for (int j = 0; j < dp.length; j++) {
for (int k = 0; k < 6; k++) {
tmp[j + k] += dp[j] / 6.0;
}
}
dp = tmp;
}
return dp;
}
十、股票的最大利润
public int maxProfit(int[] prices) {
int cost = Integer.MAX_VALUE, profit = 0;
for (int price : prices) {
cost = Math.min(cost, price);
profit = Math.max(profit, price - cost);
}
return profit;
}