1. 程式人生 > >Leetcode 516.最長回文子序列

Leetcode 516.最長回文子序列

算法 給定 最終 solution str long etc rom leet

最長回文子序列

給定一個字符串s,找到其中最長的回文子序列。可以假設s的最大長度為1000。

示例 1:
輸入:

"bbbab"

輸出:

4

一個可能的最長回文子序列為 "bbbb"。

示例 2:
輸入:

"cbbd"

輸出:

2

一個可能的最長回文子序列為 "bb"。

思路解析

分治算法去解決這道題是第一思路,即對於一個長度為n的字符串,對應於一個分治算法的狀態數組dp[n-1][n-1],該數組的值對應字符串中最長回文子序列的長度,如dp[i][j]則代表著字符串中第i位到第j位的子序列中的最長回文子序列長度為dp[i][j],明確這一點後,我們要作的即為求出dp[0][n-1]的值並輸出即可。

利用分治算法的思想,當某子串s(i,j)中s[i]與s[j]相等時,那麽其頭尾兩字符一定位於其最長回文子串中,因此該子串的最長回文子序列長度等於去掉頭尾兩字符後新子串的最長回文子序列長度加二,我們可制定公式如下:dp[i][j] = dp[i + 1][j - 1] + 2。當s[i]與s[j]不相等時,則dp[i][j] = max(de[i + 1][j],dp[i][j - 1])。有了這個規則,我們接下來只需要遍歷出該字符串s的每一個子串,即dp數組中的每一個值,最終輸出dp[0][n-1]。

 1 class Solution {
 2     public int longestPalindromeSubseq(String s) {
3 int len=s.length(); 4 int[][] dp=new int[len][len]; 5 if(len==0||len==1) return len; 6 for(int j=0;j<len;j++){ 7 dp[j][j]=1; 8 for(int i=j-1;i>=0;i--){ 9 if(s.charAt(i)==s.charAt(j)){ 10 dp[i][j]=dp[i+1][j-1]+2;
11 }else{ 12 dp[i][j]=Math.max(dp[i+1][j],dp[i][j-1]); 13 } 14 } 15 } 16 return dp[0][len-1]; 17 } 18 }

Leetcode 516.最長回文子序列