F_G

许多问题需要说清楚就可以&&走永远比跑来的重要

导航

[Leetcode] 回文问题

[1] Palindrome Number

[2] Valid Palindrome

[3] Palindrome Partitioning

[4] Palindrome Partitioning II

[5] Shortest Palindrome

[6] Palindrome Linked List

[7] Longest Palindromic Substring

一、判断一个整数是否是回文

非常直接的方法,是将这个整数的高低位进行颠倒,然后判断数字是否是相等的。但是这样做的的一个缺点是可能会溢出,比如最大的整数是2147483647(32位),将其颠倒则为7463847412肯定溢出了,如何防止整数的溢出呢?

使用double进行运算。

如果不适用double进行运算,可以对整数进行对称的比较,首先计算整数的位数N。

while N>=2

  high = num/pow(10,N-1)得到最高位

  low = num%10得到最低位

  判断之

  num = (num%pow(10,N-1))/10;

  N=N-2;

二、判断字符串是否是回文

"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Character.isLetterOrDigit(char)

三、划分的所有可能情况

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

For example, given s = "aab",
Return

[ ["aa","b"], ["a","a","b"] ]

 使用递归遍历所有的划分情况是最好的选择。为了减少递归当中判断回味子串的复杂度,我们首先求出所有的回文子串。

求回文子串的长度,可以应用到 [7] 当中。使用动态规划的思想

flag[i][j]==true, 如果i==j,活着s(i)==s(j)并且(j==i+1||flag[i+1][j-1])

代码如下:

 

 1 public class Solution {
 2     private void DFS(List<List<String>> res, String s,int start, List<String> tmpstring, boolean[][]flag){
 3         if(start==s.length()){
 4             List<String> newlist = new LinkedList<String>();
 5             newlist.addAll(tmpstring);
 6             res.add(newlist);
 7             return;
 8         }
 9         for(int i=start;i<s.length();i++){
10             if(flag[start][i]){
11                 String segment=s.substring(start,i+1);
12                 tmpstring.add(segment);
13                 DFS(res,s,i+1,tmpstring,flag);
14                 tmpstring.remove(tmpstring.size()-1);
15             }
16         }
17     }
18     public List<List<String>> partition(String s) {
19         List<List<String>> res = new LinkedList<List<String>>();
20         if(s==null||s.compareTo("")==0) return res;
21         boolean [][] flag = new boolean[s.length()][s.length()];
22         for(int i=s.length()-1;i>=0;i--){
23             for(int j=i;j<s.length();j++){
24                 if(i==j) {
25                     flag[i][j]=true;
26                     continue;
27                 }
28                 if(s.charAt(i)==s.charAt(j)){
29                     if(j==i+1||flag[i+1][j-1])
30                         flag[i][j]=true;
31                 }
32             }
33         }
34         List<String> tmpstring = new LinkedList<String>();
35         DFS(res,s,0,tmpstring,flag);
36         return res;
37     }
38 }

 

四、划分的最少次数

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

这里使用问题三当中的求取flag的方法,需要增加的代码是在每次划分的时候要更新最少的换发cut数

定义mincut[i]为从i开始到最后的子串所需的最少的cut数量。

具体还是要利用以往的子回文信息,如果从当前索引i,往右的j索引是回文,那么我们可以知道

mincut[i] = min(1+mincut[j+1],mincut[i]);

为什会要在检测到回文的时候进行更新?

存在的最少的划分方式,肯定是在各个回文的位置进行的划分,最极端的情况,每个单字符是一个回文,在不是回文的地方进行划分肯定不是最少的划分方式。

五、最短回文长度

Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.

For example:

Given "aacecaaa", return "aaacecaaa".

Given "abcd", return "dcbabcd".

字符串匹配

aacecaaa#aaacecaa

使用kmp算法得到最大前后缀为,可以得到aacecaa

然后在前面不辍多余的部分

aaacecaaa

 

六、链表回文判断

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?

方法一、修改结构

首先将链表划分为两部分,根据长度的奇偶性,不同处理方式,即可。

然后将后者reverse,在进行判断,

最后在reverse回去。

最后回复链表。

方法二、递归

使用递归的方式挑战一些另外一种思路。

我们将head指向第一个节点,如果当前节点不是最后一个节点则继续递归,否则判断tail节点和head是否相等,若相等,head = head.next,同时递归返回,继续判断,有点类似从链表构造bst的赶脚。

 1 public class Solution {
 2     public ListNode ln;
 3     public boolean isPalindrome(ListNode head) {
 4         if(head==null || head.next==null){
 5             return true;
 6         }
 7         ln=head;
 8         return isPalin(ln);
 9     }
10     public boolean isPalin(ListNode nod){
11         if(nod.next == null){
12             return nod.val == ln.val;
13         }
14         boolean res = isPalin(nod.next);
15         ln=ln.next;
16         return res && nod.val==ln.val;
17     }
18 }

 

[1] https://leetcode.com/discuss/52441/java-recursive-solution

七、最长回文子字符串的问题

使用上面提到的方法

posted on 2015-08-16 11:08  F_G  阅读(326)  评论(0编辑  收藏  举报