300.最长递增子序列
题目链接:300. 最长递增子序列 - 力扣(Leetcode)
解题思路:
这几个题都类似,最关键的地方在于确定dp数组的含义,不要盲目的认为题目的问题就是dp数组的定义。有的时候需要转换思维。
class Solution {
public int lengthOfLIS(int[] nums) {
/**
* 1.dp[i] 以下标i为序列结尾的最长严格递增子序列的长度
* 2.if(nums[i] > nums[j]) dp[i] = Math.max(dp[i], dp[j] + 1);
* 3.dp[0] = 0;
*/
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int result = 1;
for (int i = 1; i < dp.length; i++) {
for(int j = 0; j < i; j++){
if(nums[i] > nums[j]){
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
result = Math.max(result, dp[i]);
}
return result;
}
}
674.最长连续递增序列
题目链接:674. 最长连续递增序列 - 力扣(Leetcode)
解题思路:
class Solution {
public int findLengthOfLCIS(int[] nums) {
/**
* 动态规划
* 1.dp[i] 以nums[i]为结尾的连续递增子序列的最大长度
* 2.if(nums[i - 1] < nums[i]) dp[i] = dp[i - 1] + 1;
* else dp[i] = 0;
* 3.dp[i] = 1;
* 4.正向循环
*/
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int ans = 1;
for (int i = 1; i < dp.length; i++) {
if(nums[i - 1] < nums[i]) dp[i] = dp[i - 1] + 1;
else dp[i] = 1;
ans = Math.max(ans, dp[i]);
}
return ans;
}
}
718.最长重复子数组
题目链接:718. 最长重复子数组 - 力扣(Leetcode)
解题思路:
这个题需要注意的就是dp数组的初始化问题。不可以仅仅初始化(0,0)。
class Solution {
public int findLength(int[] nums1, int[] nums2) {
/**
* 1.dp[i][j] 以nums1[i]结尾以及nums2[j]结尾的子数组的最长公共长度
* 2.if(nums1[i] == nums2[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
* else dp[i][j] = 0;
*/
int ans = 0;
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
for(int i = 0; i < nums1.length; i++){
if(nums1[i] == nums2[0]) dp[i][0] = 1;
ans = Math.max(ans, dp[i][0]);
}
for(int i = 1; i < nums2.length; i++){
if(nums1[0] == nums2[i]) dp[0][i] = 1;
ans = Math.max(ans, dp[0][i]);
}
for (int i = 1; i < nums1.length; i++) {
for (int j = 1; j < nums2.length; j++) {
if(nums1[i] == nums2[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
ans = Math.max(ans, dp[i][j]);
}
}
return ans;
}
}
剑指offer 12.矩阵中的路径
题目链接:剑指 Offer 12. 矩阵中的路径 - 力扣(Leetcode)
解题思路:
class Solution {
public boolean exist(char[][] board, String word) {
/**
首先找到起始首字母,然后进行递归判断
*/
char sw = word.charAt(0);
int m = board.length;
int n = board[0].length;
boolean[][] used = new boolean[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(board[i][j] == sw){
if(hasWord(board, used, word, i, j, 0) == true) return true;
}
}
}
return false;
}
public boolean hasWord(char[][] board, boolean[][] used, String word, int x, int y, int index){
// 判断是否不需要该字符。长度已经够了
if(index == word.length()) return true;
// 判断横纵坐标是否符合要求,没有越界
if(x < 0 || x >= board.length) return false;
if(y < 0 || y >= board[0].length) return false;
// 判断元素是否已经被使用
if(used[x][y] == true) return false;
// 判断元素是否匹配
if(board[x][y] != word.charAt(index)) return false;
used[x][y] = true;
// 继续判断下一个元素
boolean left = hasWord(board, used, word, x - 1, y, index + 1);
boolean right = hasWord(board, used, word, x + 1, y, index + 1);
boolean up = hasWord(board, used, word, x, y + 1, index + 1);
boolean down = hasWord(board, used, word, x, y - 1, index + 1);
used[x][y] = false;
return left || right || up || down;
}
}