Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中查找字符串中最长的回文_Python_Algorithm - Fatal编程技术网

在Python中查找字符串中最长的回文

在Python中查找字符串中最长的回文,python,algorithm,Python,Algorithm,我正在努力解决LeetCode上的问题。问题陈述是: 给定一个字符串s,查找s中最长的回文子字符串。您可以假定s的最大长度为1000 例如: 注:“aba”也是一个有效答案。 例如: 我提出了以下解决方案(包括一些测试用例): 导入pytest 类解决方案: def最长回文(self,s): 候选者=“” 最长=“” 包含回文=False 对于i,枚举中的字符: 如果i==0: 候选字符 elif i==1: 如果s[1]==s[0]: 候选者=self.get_回文(s,开始=0,结束=1)

我正在努力解决LeetCode上的问题。问题陈述是:

给定一个字符串s,查找s中最长的回文子字符串。您可以假定s的最大长度为1000

例如:

注:“aba”也是一个有效答案。 例如:

我提出了以下解决方案(包括一些测试用例):

导入pytest
类解决方案:
def最长回文(self,s):
候选者=“”
最长=“”
包含回文=False
对于i,枚举中的字符:
如果i==0:
候选字符
elif i==1:
如果s[1]==s[0]:
候选者=self.get_回文(s,开始=0,结束=1)
如果i>=2:
如果char==s[i-1]:
候选者=self.get_回文(s,start=i-1,end=i)
elif char==s[i-2]:
候选者=self.get_回文(s,start=i-2,end=i)
如果len(候选)>len(最长):
最长=候选人
回程最长
@静力学方法
def get_回文(s,开始,结束):
回文=s[开始:结束+1]
当末端0)和(结束<长度-1):
开始-=1
结束+=1
如果s[start]==s[end]:
回文组=s[start]+回文组+s[end]
其他:
打破
返回回文
@静力学方法
定义所有相同(项目):
返回全部(项中的项的项==项[0]
def测试_1():
assert Solution().longestPalindrome(“babad”)=“bab”
def测试_2():
断言解决方案().longestPalindrome(“cbbd”)=“bb”
def测试_3():
assert Solution().longestPalindrome(“abba”)=“abba”
def测试_4():
assert Solution().longestPalindrome(“a”)=“a”
def测试_5():
断言解决方案().longestPalindrome(“ccc”)=“ccc”
def测试_6():
assert Solution().longestPalindrome(“aaaa”)=“aaaa”
def测试_7():
assert Solution().longestPalindrome(“aaabaaa”)=“aaabaaa”
如果名称=“\uuuuu main\uuuuuuuu”:
pytest.main([[uuuuu文件])
问题是我得到了一个“超过时间限制”错误:

我的理解是,该算法的时间复杂度为O(n^2),因为它会检查每个字符的回文长度,可能多达n个字符。LeetCode的解决方案中还有O(n^2)算法(Java)


我猜Python的时间限制有点太严格了,它比Java慢。或者我遗漏了什么,并且我的解决方案的时间复杂度实际上大于O(n^2)?

您失败的测试字符串似乎只由a组成。这是最坏的情况,它实际上是O(n³)而不是O(n²),因为在
中有另一个隐藏循环。(起初,我还认为字符串上的slice操作符
[:]
会进行复制,但事实并非如此。)

您需要调用所有相同的
,因为您在主函数中区分了“aa”和“aba”两种情况。但是您不需要在循环中这样做,因为您将只在第一个
中添加相同的字母,而在
获取回文
中循环。因此,一个快速解决方案是只测试一次所有字符是否相同:

    if Solution.all_same(palindrome):
        while end < len(s) - 1:
            if s[end+1] == s[start]:
                end += 1
                palindrome += s[end]
            else:
                break
总的来说,代码看起来相当不整洁,带有所有的
中断和不必要的大小写区分。为什么要将索引和
回文
作为单独的实体保存在
获取回文
中,而您必须保持同步

在我看来,这是一个更整洁的版本:

class Solution:
    def longestPalindrome(self, s):
        longest = ""

        for i, _ in enumerate(s):
            candidate = self.get_palindrome(s, start = i, end = i)

            if len(candidate) > len(longest):
                longest = candidate

        return longest

    @staticmethod
    def get_palindrome(s, start, end):
        while end + 1 < len(s) and s[end+1] == s[start]:
            end += 1

        while start > 0 and end + 1 < len(s) and s[start - 1] == s[end + 1]:
            start -= 1
            end += 1

        return s[start:end + 1]

这在“abababab”这样的字符串上仍然不理想,但在您的情况下应该足够快。

我尝试了“动态规划”的思想,即找到“0阶”回文的中心,然后随着深度的增加和不匹配的发生而修剪

修剪是在列表comps中完成的,应该相对较快,但仍然是O(n^2)


这是我发现的获取最长回文及其长度的方法。我认为这很容易理解

首先,我将这个单词添加到一个字符数组中,然后我将第一个字母与所有其他字母向后检查。然后继续下一个字符。使用if-else和for循环得到答案,最后使用hashset得到最长的回文

public static void main(String[] args) {

    Scanner in = new Scanner(System.in);

System.out.println(longestPalSubstr(in.nextLine().toLowerCase()));


}




static String longestPalSubstr(String str) {

       char [] input = str.toCharArray();
       Set<CharSequence> out = new HashSet<CharSequence>();

      int n1 = str.length()-1;


      for(int a=0;a<=n1;a++)
       {
          for(int m=n1;m>a;m--)
          {

          if(input[a]==input[m])
          {

           String nw = "",nw2="";

           for (int y=a;y<=m;y++)
           {

                nw=nw+input[y];
           }
           for (int t=m;t>=a;t--)
           {

               nw2=nw2+input[t];
           }


           if(nw2.equals(nw))
           {

                out.add(nw);


               break;
           }
       }

     }

   }


    int a = out.size();
    int maxpos=0;
    int max=0;
    Object [] s = out.toArray();

    for(int q=0;q<a;q++)
    {

        if(max<s[q].toString().length())
        {
            max=s[q].toString().length();
            maxpos=q;
        }
    }


   String output = "longest palindrome is : "+s[maxpos].toString()+" and the lengths is : "+ max; 
   return output;



}
publicstaticvoidmain(字符串[]args){
扫描仪输入=新扫描仪(系统输入);
System.out.println(longestPalSubstr(in.nextLine().toLowerCase());
}
静态字符串longestplasubstr(字符串str){
char[]input=str.toCharArray();
Set out=新的HashSet();
int n1=str.length()-1;
对于(int a=0;aa;m--)
{
如果(输入[a]==输入[m])
{
字符串nw=“”,nw2=“”;
对于(int y=a;y=a;t--)
{
nw2=nw2+输入[t];
}
如果(nw2.等于(nw))
{
加上(西北);
打破
}
}
}
}
int a=out.size();
int-maxpos=0;
int max=0;
对象[]s=out.toArray();

对于(intq=0;qI)来说,没有深入研究您的代码,但实际上标准的方法是使用动态编程。我猜时间限制“知道”big-O的工作原理是什么,也就是说,它是一个渐进的东西。所以它会以某种方式得到一个估计,你的解决方案需要n的时间,然后看看你在100n或类似的情况下做什么。然后使用一个足够大的n,这样设置成本就无关紧要了。我提交了第一个解决方案,它被接受了。事实上,我错过了所有相同的
方法d也是O(n),所以我运行的是O(n^3)方法,而不是O(n^2)方法。(您的解决方案也确实更整洁;开始扩展是有意义的。)
    if Solution.all_same(palindrome):
        while end < len(s) - 1:
            if s[end+1] == s[start]:
                end += 1
                palindrome += s[end]
            else:
                break
        elif i >= 2:
            if char == s[i-1]:
                candidate = self.get_palindrome(s, start=i-1, end=i)
            else:
                candidate = self.get_palindrome(s, start=i, end=i)
class Solution:
    def longestPalindrome(self, s):
        longest = ""

        for i, _ in enumerate(s):
            candidate = self.get_palindrome(s, start = i, end = i)

            if len(candidate) > len(longest):
                longest = candidate

        return longest

    @staticmethod
    def get_palindrome(s, start, end):
        while end + 1 < len(s) and s[end+1] == s[start]:
            end += 1

        while start > 0 and end + 1 < len(s) and s[start - 1] == s[end + 1]:
            start -= 1
            end += 1

        return s[start:end + 1]
class Solution:
    def longestPalindrome(self, s):
        longest = ""
        i = 0
        l = len(s)

        while i < l:
            end = i

            while end + 1 < l and s[end + 1] == s[i]:
                end += 1

            candidate = self.get_palindrome(s, i, end)

            if len(candidate) > len(longest):
                longest = candidate

            i = end + 1

        return longest

    @staticmethod
    def get_palindrome(s, start, end):
        while start > 0 and end + 1 < len(s) and s[start - 1] == s[end + 1]:
            start -= 1
            end += 1

        return s[start:end + 1]
class Solution:
    def longestPalindrome(self, s):

        s = '>' + s + '<'  # add guard values

        # make lists of '0_th order' palindrome 'centers', even and odd

        evn = [i for i, a in enumerate(zip(s, s[1:])) if a[0] == a[1]]

        odd = [i + 1 for i, a in enumerate(zip(s, s[2:])) if a[0] == a[1]]

        # prune lists of centers when elements +/- j from centers don't match

        evn_last, odd_last = [[1], 0], [[1], 1]

        j = 1
        while evn:
            evn_last = (evn, j)
            evn = [e for e in evn if s[e - j] == s[e + j + 1]]
            j += 1

        j = 1
        while odd:
            odd_last = (odd, j)
            odd = [e for e in odd if s[e - j] == s[e + j]]
            j += 1

        # determine longest, construct palindrome

        if 2 * evn_last[1] > 2 * odd_last[1] - 1:

            cntr = evn_last[0][0]
            pal = s[cntr] + s[cntr + 1]
            for i in range(1, evn_last[1]):
                pal = s[cntr - i] + pal + s[cntr + i + 1]
        else:
            cntr = odd_last[0][0]
            pal = s[cntr]
            for i in range(1, odd_last[1]):
                pal = s[cntr - i] + pal + s[cntr + i]
        return pal
S = Solution()

%timeit S.fred_longestPalindrome("aba"*300)
17.8 ms ± 230 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit S.Kurt_longestPalindrome("aba"*300)
52.8 ms ± 108 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
public static void main(String[] args) {

    Scanner in = new Scanner(System.in);

System.out.println(longestPalSubstr(in.nextLine().toLowerCase()));


}




static String longestPalSubstr(String str) {

       char [] input = str.toCharArray();
       Set<CharSequence> out = new HashSet<CharSequence>();

      int n1 = str.length()-1;


      for(int a=0;a<=n1;a++)
       {
          for(int m=n1;m>a;m--)
          {

          if(input[a]==input[m])
          {

           String nw = "",nw2="";

           for (int y=a;y<=m;y++)
           {

                nw=nw+input[y];
           }
           for (int t=m;t>=a;t--)
           {

               nw2=nw2+input[t];
           }


           if(nw2.equals(nw))
           {

                out.add(nw);


               break;
           }
       }

     }

   }


    int a = out.size();
    int maxpos=0;
    int max=0;
    Object [] s = out.toArray();

    for(int q=0;q<a;q++)
    {

        if(max<s[q].toString().length())
        {
            max=s[q].toString().length();
            maxpos=q;
        }
    }


   String output = "longest palindrome is : "+s[maxpos].toString()+" and the lengths is : "+ max; 
   return output;



}
class Solution:
    def longestPalindrome(self, s):   
        paliandr = ''
        len_s = len(s)


        def if_pal_singl(s,i,dabl):
            pal = s[i-dabl:i+1]
            indx_left = i-dabl
            indx_right = i
            while (indx_left-1 in range(len_s) and indx_right+1 in range(len_s)):
                indx_left -=1
                indx_right +=1
                if s[indx_left] == s[indx_right]:
                    pal = s[indx_left]+pal+s[indx_right]
                else: 
                    break
            return pal  


        dabl = 0        
        for i in range(1,len_s-1):
            if s[i] == s[i+1]:
                dabl+=1
                continue
            pal = if_pal_singl(s,i,dabl)
            dabl = 0
            if len(pal) > len(paliandr):
                paliandr = pal
        print (paliandr)
if __name__ == "__main__":
    Solution().longestPalindrome('abababab')