都是在一个一维数组中寻找满足题目要求的子序列,都要用二维的dp数组,在原数组的元素上讨论寻找状态转移方程。复杂度都是O(n^2)
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int len1 = text1.length();
int len2 = text2.length();
int[][] dp = new int[len1+1][len2+1];
for(int i = 0; i < len1; i++) {
dp[i][0] = 0;
}
for(int j = 0; j < len2; j++) {
dp[0][j] = 0;
}
for(int i = 1; i <= len1; i++) {
for(int j = 1; j <= len2; j++) {
if(text1.charAt(i-1) == text2.charAt(j-1)) {
dp[i][j] = dp[i-1][j-1] + 1;
}else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);//这里出错的原因是状态转移没有思考清楚
}
}
}
return dp[len1][len2];
}
}
class Solution {
public int findLength(int[] A, int[] B) {
int len1 = A.length;
int len2 = B.length;
int[][] dp = new int[len1+1][len2+1];
//初始化
for(int i = 0; i < len1; i++) {
dp[i][0] = 0;
}
for(int j = 0; j < len2; j++) {
dp[0][j] = 0;
}
int ans = 0;
//找出最长公共子数组
for(int i = 1; i <= len1; i++) {
for(int j = 1; j <= len2; j++) {
if(A[i-1] == B[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
}else {
dp[i][j] = 0;
}
ans = Math.max(dp[i][j], ans);
}
}
return ans;
}
}
class Solution {
public int longestPalindromeSubseq(String s) {
int len = s.length();
if(len <= 1) return len;
int[][] dp = new int[len+1][len+1];
for(int i = 0; i < len; i++) {
dp[i][i] = 0;
}
char[] c = new char[len];
int k = 0;
for(int i = len-1; i >= 0; i--) {
c[k++] = s.charAt(i);
}
for(int i = 1; i <= len; i++) {
for(int j = 1; j <= len; j++) {
if(c[j-1] == s.charAt(i-1)) {
dp[i][j] = dp[i-1][j-1] + 1;
}else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[len][len];
}
}
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(s == null || len < 1) return s;
int[][] dp = new int[len][len];
String ans = "";
int r = 1;
int l = 0;
String t = "";
for(int i = 1; i < len; i++) {
dp[i][i] = 1;
for(int j = 0; j < i; j++) {
if(s.charAt(i) == s.charAt(j)) {
if(i - j < 3) {
dp[j][i] = 1;
}else {
dp[j][i] = dp[j + 1][i - 1];
}
}else {
dp[j][i] = 0;
}
if(dp[j][i] == 1) {
int temp = i - j + 1;
if(temp > r) {
r = temp;
l = j;
}
}
}
}
return s.substring(l,r+l);
}
}
class Solution {
public int longestArithSeqLength(int[] A) {
int len = A.length;
if(len < 2) return len;
//int[][] dp = new int[len][len];
int[][] dp = new int[len][20001];
int ans = 0;
for(int i = 1; i < len; i++) {
for(int j = 0; j < i; j++) {
int num = A[i] - A[j] + 10000;
if(dp[j][num] > 0) {
dp[i][num] = Math.max(dp[i][num], dp[j][num] + 1);
}else {
dp[i][num] = 2;
}
ans = Math.max(ans,dp[i][num]);
}
}
return ans;
}
}
class Solution {
public int lenLongestFibSubseq(int[] A) {
int len = A.length;
if(len <= 2) return len;
int[][] dp = new int[len][len];//dp以A[i]为最后一个数的最长斐波拉契子序列的长度
for(int i = 0; i < len; i++) {
Arrays.fill(dp[i], 2);//初始化
}
int ans = 0;
//从前面的数组中选两个元素,如果相等就长度增一
int l = 0;
int r = 0;
for(int i = 1; i < len; i++) {
r = i - 1;
l = 0;
while(l < r) {
int sum = A[l] + A[r];
if(sum == A[i]) {
dp[r][i] = Math.max(dp[r][i], dp[l][r] + 1);
ans = Math.max(ans, dp[r][i]);
l++;
r--;
}else if(sum < A[i]){
l++;
}else {
r--;
}
}
}
return ans;
}
}