zoukankan      html  css  js  c++  java
  • LeetCode 5_Longest Palindromic Substring


    LeetCode 5_Longest Palindromic Substring 

    题目描写叙述:

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 也即:求字符串中最长回文子串。

    回文是什么我就不多少了。能够百度下!

    方法一:暴力法(O(n^3))

    两层循环扫描字符串的全部子串,之后推断选出的字符子串是否是回文,若是则看其长度!

    代码例如以下:

    class Solution {
    public:
        string longestPalindrome(string s) 
        {
            // 暴力法O(n^3)
            int n = s.size();
    		if (n == 0 || n == 1)
    			return s;
    		int maxLength = 1;
    		int k1 = 0, k2 = 0;
    		for (int i = 0; i < n; i++)
    		{
    			for (int j = i + 1; j < n; j++)
    			{
    				int k = 0;
    				int sign = 0;
    				while (k < (j - i + 1)/2 && s[i + k] == s[j - k])
    					k++;
    				if(k == (j - i + 1) / 2 )
    				{
    					sign = 1;
    					if (j - i + 1 > maxLength)
    					{
    						maxLength = j - i + 1;
    						k1 = i;
    						k2 = j;
    						if (maxLength == n - i)
    						    return s.substr(k1,k2+1);
    					}
    				}
    			}
    		}
    		return s.substr(k1,k2+1);
    }
    不用说,肯定超时。显然暴力法有非常大的优化空间。在推断子串的时候肯定有非常多反复的情况,能够用一个表记录已经推断的情况!

    因为题目说能够假定字符串的长度不超过1000,所以建立一个table[1000][1000] 的bool表,初始化为false。如果某子串(如果 i 到 j )为回文。令table[ i ][ j ]为true。之后推断的时候先查表和更新表。代码例如以下:

    class Solution {
    public:
        string longestPalindrome(string s) 
        {
        		int n = s.length();
    		if(n == 0 || n == 1)
    		    return s;
    		int maxLength = 1;
    		int palindromBegin = 0;
    		bool table[1000][1000] = {false};
    		for(int i = 0; i < n; i++)
    			table[i][i] = true;
    		for (int i = 0; i < n; i++)
    			if(s[i] == s[i + 1])
    			{
    			    table[i][i + 1] = true;
    				maxLength = 2;
    				palindromBegin = i;
    			}
    		for (int len = 3; len <= n ; len++)
    		{
    			for (int i = 0; i < n - len + 1; i++)
    			{
    				int j = i + len - 1;
    				if (s[i] == s[j] && table[i + 1][j - 1] == true)
    				{
    				    table[i][j] = true;
    					maxLength = len;
    					palindromBegin = i;
    				}
    			}
    		}
    		return s.substr(palindromBegin, maxLength);
    }

    上面的方法时间复杂度为O(n^2),能够满足题目的要求。

    事实上还能够考虑回文的中心点。向两边扩展(回文的中心点能够是摸个字符。也能够是某两个字符的中间),代码例如以下:

    string expandAroundCenter(string s, int c1, int c2) {
      int l = c1, r = c2;
      int n = s.length();
      while (l >= 0 && r <= n-1 && s[l] == s[r]) {
        l--;
        r++;
      }
      return s.substr(l+1, r-l-1);
    }
    class Solution {
    public:
        string longestPalindrome(string s) 
        {
          int n = s.length();
          if (n == 0) return "";
          string longest = s.substr(0, 1);  // a single char itself is a palindrome
          for (int i = 0; i < n-1; i++) {
            string p1 = expandAroundCenter(s, i, i);
            if (p1.length() > longest.length())
              longest = p1;
         
            string p2 = expandAroundCenter(s, i, i+1);
            if (p2.length() > longest.length())
              longest = p2;
          }
          return longest;
        }
    };
    代码的复杂度为O(n^2)。另一种说复杂度为O(n)的方法,只是我没去看,有兴趣的能够看下: http://www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html。



  • 相关阅读:
    yafu安装使用方法以及mismatched parens解决方法
    Bubble Babble Binary Data Encoding的简介以及bubblepy的安装使用方法
    python-gzip解压缩(实验吧SOS)
    python用模块zlib压缩与解压字符串和文件的方法
    IDA-IDC脚本编写语法
    南邮CTF密码学,mixed_base64
    各种类型文件头标准编码
    实验吧,心中无码
    Vue + webpack的纯前端项目如何配置外部配置文件
    js小技巧
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7103186.html
Copyright © 2011-2022 走看看