A very classical problem. The most naive way is to enumerate all substring and then check if each string is a valid palindrome. This would give O(n^3) time complexity. A better way is to start from a character as the center and expand to left and right to see the longest palindrome we could obtain. We need to check two cases: both even length and odd length. This would give O(n^2) time complexity.
public String longestPalindrome(String s) { int n = s.length(); if(n == 0) return s; // corner case int ma = 0; int mai = 0, maj = 0; for(int i = 0; i < n; i++) { // case 1 odd int left = i, right = i; while(left >= 0 && right < n && s.charAt(left) == s.charAt(right)) { left--; right++; } if(ma < right - left - 1) { ma = right - left - 1; mai = left + 1; maj = right - 1; } } for(int i = 0; i < n-1; i++) { // case 2 even int left = i, right = i+1; while(left >= 0 && right < n && s.charAt(left) == s.charAt(right)) { left--; right++; } if(ma < right - left - 1) { ma = right - left - 1; mai = left + 1; maj = right - 1; } } return s.substring(mai, maj+1); }
Another way is to use DP to solve this problem. However, the time complexity is still O(n^2) and space complexity is O(n^2), too. The steps are as follow:
- We use dp[i][j] to represent whether s[i...j] is a valid palindrome or not.
- if i == j, then dp[i][j] = true.
- if i+1 == j and s[i] == s[j], dp[i][j] = true.
- otherwise, only if dp[i+1][j-1] == true and s[i] == s[j], dp[i][j] = true.
- During the process, whenever we find a new valid palindrome, we update the current max and record the index
public String longestPalindrome(String s) { int n = s.length(); if(n == 0) return s; // corner case boolean[][] dp = new boolean[n][n]; int ma = 0; int mai = 0, maj = 0; // index of the longest palindrome string for(int i = n-1; i >= 0; i--) { for(int j = i; j < n; j++) { if(i == j) { // case 1 dp[i][j] = true; if(ma < j-i+1) { ma = j-i+1; mai = i; maj = j; } } else if(i+1 == j) { // case 2 if(s.charAt(i) == s.charAt(j)) { dp[i][j] = true; if(ma < j-i+1) { ma = j-i+1; mai = i; maj = j; } } else dp[i][j] = false; } else { // case 3 if(s.charAt(i) == s.charAt(j) && dp[i+1][j-1] == true) { dp[i][j] = true; if(ma < j-i+1) { ma = j-i+1; mai = i; maj = j; } } else dp[i][j] = false; } } } return s.substring(mai, maj+1); }
没有评论:
发表评论