【问题标题】:How do I efficiently determine the longest individual character palindrome in a given string?如何有效地确定给定字符串中最长的单个字符回文?
【发布时间】:2011-11-20 18:52:50
【问题描述】:

给定一个包含字符 [A-Z] 的长度为 N 的字符串,我如何确定单个字符的最长回文?

我会用一个例子来说明这一点:

给定字符串:JOHNOLSON 在分析字符串时,我们发现我们有一个带有字符 O 的回文,使得字符串看起来像 JOHN OLSONO 的回文长度为 7,基本上看起来像 O--O--O强>。另外,请注意有一个带有 N 的回文,但它的长度仅为 6。

另一个例子, 给定字符串:ABCJOHNOLSON 给出与上面相同的结果,长度为 7 的 O 的回文看起来像 O--O --O

然而,对于给定的字符串ABCJOHNOLSONDA,最长的单个字符回文长度为14,字符A看起来像A------------A

其他简单的例子包括:

ABA --> A-A(长度为3)

ABAXYZ --> A-A(长度为3)

ABAXYZA --> A---A(长度为 5),而不是长度为 7,因为 A-A---A 不是 A 的回文。

请特别注意最后一个示例,因为它说明了问题的细微差别之一。

【问题讨论】:

  • 对于您要查找的内容,必须有一个比“回文”更好的术语,因为您的大多数示例都不是回文。
  • 考虑一个示例字符串ABCDAEEALMNA,当考虑A时看起来像A---A--A---A,这是一个大小为12的回文(当你忽略其余字符的唯一性时) ,但考虑字符串ABCDAEEALMNOA,其中整个字符串不再是回文,而是一个小得多的子字符串成为最长的回文,即末尾长度为5的A---A
  • 我了解您感兴趣的pattern,它只是不符合术语回文的字典定义。我想知道您正在寻找的是否有正则表达式解决方案。
  • @BlastFurnace 我明白你在说什么。你会建议用不同的方式来思考这个问题吗?它以回文的形式出现在我面前,所以我不确定它还能被描述为什么。

标签: algorithm palindrome


【解决方案1】:

您可以在线性时间内完成,它在here 中使用代码示例进行了描述。

【讨论】:

    【解决方案2】:

    这是我想出来的,我不知道它的效率如何。

    对于字母表中的每个字母, 查找此字母的第一个和最后一个匹配项。 虽然子字符串不是该字母的回文(易于检查), 找到两边的下一个字母,这样每个可能的组合都是 检查。取最长的一个并存放它。 取最长的一个。

    【讨论】:

    • 当您说在两边找到下一个字母时,您的意思是您当前正在搜索的字符的下一个实例吗?这对于某些字符串会失败,例如“ABAAAACAA”
    • @JordanBentley:不,我的意思是(例如)尝试 0,7 然后 0,6 然后 0,4 然后 0,3 然后 0,2 然后 0,0 然后 2,7 然后 2, 6 然后 2,4 然后 2,3 然后 2,2 然后 3,7 然后 3,6 然后......你明白了:) 但是如果在某些条件下找到回文,你可以打破,立即说。
    • 啊,这更有意义。如果我理解正确,那会起作用,但最坏情况的复杂性将是 O(n!)
    • @JordanBentley:是的,我认为它可能不是那么好。哦,好吧,这是另一种选择:)
    【解决方案3】:

    绝对不是最优的。假设输入字符串都是小写的。

    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 2021-05-23
      • 2020-12-14
      • 2012-09-14
      相关资源
      最近更新 更多