小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
最长回文子序列
题目
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
来源:力扣(LeetCode)
思路
1.动态规划,dp[i][j]表示从i到j位置的字符串的最长回文子序列,必然有0<=i<=j<=n-1(n为字符串的长度)
2.只有一个字符的情况能够形成长度为1的回文子序列
3.比较s.charAt(i)和s.charAt(j)位置的值是否相等相等的话在dp[i+1][j-1]的基础上+2,可以理解为向两边扩充
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
int[][] dp = new int[n][n];
for(int i=n-1;i>=0;i--){
dp[i][i]=1;
char c1 = s.charAt(i);
for(int j=i+1;j<n;j++){
char c2 = s.charAt(j);
if(c1==c2){
dp[i][j]=dp[i+1][j-1]+2;
}else{
dp[i][j]=Math.max(dp[i+1][j],dp[i][j-1]);
}
}
}
return dp[0][n-1];
}
}
最长重复子数组
题目
给两个整数数组 A
和 B
,返回两个数组中公共的、长度最长的子数组的长度。
思路
1.设n = A.length, m = B.length,那么dp[i][j]表示从i到n-1的字符串和从j到m-1的字符串的最长公共前缀
代码
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
int[][] dp = new int[n+1][m+1];
int res = 0;
for(int i=n-1;i>=0;i--){
for(int j=m-1;j>=0;j--){
dp[i][j]=nums1[i]==nums2[j]?dp[i+1][j+1]+1:0;
res=Math.max(res,dp[i][j]);
}
}
return res;
}
}