文章目录
前言
提示:这里为每天自己的学习内容心情总结;
Learn By Doing,Now or Never,Writing is organized thinking.
现在就是巩固,每天看一点面经,刷题,打磨项目,积少成多。
需要持续的积累。
先多,后少。
提示:以下是本篇文章正文内容
一、今天学习了什么?
- 刷题;
二、关于问题的答案
1、动态规划
java
public int minDistance(String word1, String word2) {
/**
* dp[i][j],word1下标从(0,i-1)转换成word2下标从(0,j-1)的最少操作数
*/
int m = word1.length();
int n = word2.length();
int[][] dp = new int[m + 1][n + 1];
// base
for (int i = 1; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 1; j <= n; j++) {
dp[0][j] = j;
}
// dp过程
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
// 如果两个字符相同,那么就不需要操作
dp[i][j] = dp[i - 1][j - 1];
} else {
// 如果两个字符不同,有三种情况
// 1、替换
// 2、word2删除
// 3、word1删除
dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1;
}
}
}
return dp[m][n];
}
int min(int a, int b, int c) {
a = a < b ? a : b;
a = a < c ? a : c;
return a;
}
- 647. 回文子串(⭐⭐⭐⭐⭐)- 没有思路
java
public int countSubstrings(String s) {
/**
* dp[i][j],字符串s下标从(i,j)是否为回文字符串,true or false
*/
boolean[][] dp = new boolean[s.length()][s.length()];
int ans = 0;
// dp 过程
// 注意遍历顺序,从下到上,从左到右
// 由于判断s[i,j]是否为回文字符串,和s[i+1,j-1]有关
for (int i = s.length() - 1; i >= 0; i--) {
for (int j = i; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
if (j - i <= 1) {
ans++;
dp[i][j] = true;
} else if (dp[i + 1][j - 1]) {
ans++;
dp[i][j] = true;
}
}
}
}
return ans;
}
- 516. 最长回文子序列(⭐⭐⭐⭐⭐)
java
public int longestPalindromeSubseq(String s) {
/**
* dp[i][j],代表s从下标(i,j)中最长的回文子序列
*/
int[][] dp = new int[s.length()][s.length()];
// base
for (int i = 0; i < s.length(); i++) {
dp[i][i] = 1;
}
// dp process
for (int i = s.length() - 2; i >= 0; i--) {
for (int j = i + 1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = dp[i + 1][j - 1] + 2;
} else {
// 如果不等的话,就是等于[i+1,j] or [i,j-1]的最大回文子序列长度
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][s.length() - 1];
}
2、贪心算法
java
public int findContentChildren(int[] g, int[] s) {
/**
* - 我的思路是将胃口和饼干数量从小到大排序
* - 排序完毕后,依次将胃口从小到大的人满足
*/
Arrays.sort(g);
Arrays.sort(s);
int ans = 0;
int index = 0;
for (int i = 0; i < g.length; i++) {
while (index < s.length && g[i] > s[index]) {
index++;
}
if (index < s.length) {
ans++;
}
index++;
if (index >= s.length) {
break;
}
}
return ans;
}
- 376. 摆动序列(⭐⭐⭐⭐⭐)- 毫无思路
java
public int wiggleMaxLength(int[] nums) {
/**
* prediff:记录之前的摆动
* curdiff:现在的摆动
*/
int ans = 1;// 摆动序列的最长子序列的长度,初始化为1
int prediff = 0;
int curdiff = 0;
for (int i = 1; i < nums.length; i++) {
curdiff = nums[i] - nums[i - 1];
if ((prediff <= 0 && curdiff > 0) || (prediff >= 0 && curdiff < 0)) {
ans++;
prediff = curdiff;
}
}
return ans;
}
- 55. 跳跃游戏(⭐⭐⭐⭐⭐)
java
public boolean canJump(int[] nums) {
/**
* cover : 能跳到的覆盖范围下标
*/
int cover = nums[0];
for (int i = 0; i <= cover; i++) {
cover = Math.max(cover, i + nums[i]);
if (cover >= nums.length - 1) {
return true;
}
}
return false;
}
- 45. 跳跃游戏 II(⭐⭐⭐⭐⭐)- 难了很多
java
public int jump(int[] nums) {
/**
* cur : 当前这一步能走到的最大下标范围
* next : 下一步能跳跃的最大范围
*/
int ans = 0;
int cur = 0;
int next = 0;
for (int i = 0; i <= cur && cur < nums.length - 1; i++) {
next = Math.max(next, i + nums[i]);
if (i == cur) {
ans++;
cur = next;
}
}
return ans;
}
java
public int largestSumAfterKNegations(int[] nums, int k) {
/**
* - 先将数组从小到大排序
* - 反转数组前面的负数
* - 判断k值
*/
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] < 0 && k > 0) {
nums[i] = -nums[i];
k--;
}
}
if (k > 0 && k % 2 == 1) {
Arrays.sort(nums);
nums[0] = -nums[0];
}
int res = 0;
for (int i = 0; i < nums.length; i++) {
res += nums[i];
}
return res;
}
总结
提示:这里对文章进行总结:
今天结束了动态规划篇的刷题,进入了贪心算法。
贪心算法指的是每一步都是最优解,然后达到最后结果的全局最优解。也需要将一个问题拆分成为小问题。