给定一个长度为N的字符串[A-Z],如何确定单个字符的最长回文?
我将用一个例子来说明这一点:
给定字符串:JOHNOLSON
在分析字符串时,我们发现我们有一个字符为 O
的回文,使得该字符串看起来像J
O
HN
的 O
LS
的 O
N
。 O
的回文长度为7,基本上类似于 O
--
O
{{1 }}的 --
即可。另外,请注意有一个O
的回文,但它的长度只有6。
另一个例子,
给定字符串:N
给出与上面相同的结果,其中ABCJOHNOLSON
长度为7的回文看起来像 O
O
--
O
的 --
但是,对于给定的字符串O
,最长的单个字符回文长度为14,字符ABCJOHNOLSONDA
看起来像 A
{{1} }的 A
其他简单的例子包括:
------------
- > A
ABA
A
(长度3)
-
- > A
ABAXYZ
A
(长度3)
-
- > A
ABAXYZA
A
(长度为5),而不是长度为7,因为 ---
A
A
-
A
不是信---
的回文。
要特别注意最后一个例子,因为它说明了问题的一个细微差别。
答案 0 :(得分:5)
你可以在线性时间内完成它,它用代码样本描述here。
答案 1 :(得分:0)
这是我想出的,我不知道它的效率如何。
For every letter in the alphabet, Find the first and last occurrence of this letter. While the substring is not a palindrome for that letter (easy to check), find the next letter on both sides so that every possible combination is checked. Take the longest one and store it. Take the longest one.
答案 2 :(得分:0)
绝对不是最佳的。假设输入字符串全部为小写。
using System;
using System.Collections.Generic;
public class LongestPalindrome
{
public int longest(string s)
{
Dictionary<char, List<int>> indices =
new Dictionary<char, List<int>>();
// find all indices for each letter
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
if (!indices.ContainsKey(c))
indices.Add(c, new List<int>());
indices[c].Add(i);
}
int max = Int32.MinValue;
for (int i = (int)'a'; i <= (int)'z'; i++)
{
char c = (char)i;
// in case a letter didn't appear at all in the input string
if (!indices.ContainsKey(c)) continue;
List<int> indexList = indices[c];
// in case a letter appeared only once in the input string
if (indexList.Count == 1) max = Math.Max(max, 1);
for (int j = 0; j < indexList.Count; j++)
{
for (int k = j + 1; k < indexList.Count; k++)
{
int dist = indexList[k] - indexList[j] + 1;
string sub = s.Substring(indexList[j], dist);
if (isPalendrome(sub, c))
max = Math.Max(max, dist);
}
}
}
return max;
}
bool isPalendrome(string s, char c)
{
int i = 0;
while(i < s.Length - 1 - i)
{
if (s[i] != c && s[s.Length - 1 - i] != c)
{
i++;
continue;
}
if (s[i] != s[s.Length - 1 - i]) return false;
i++;
}
return true;
}
}