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。



  • 相关阅读:
    在Salesforce中实现对Object的增删改查操作
    在Salesforce中通过编写C#程序调用dataloadercliq的bat文件取触发调用data loader来批量处理数据
    在Salesforce中通过dataloadercliq调用data loader来批量处理数据
    【LeetCode】189. Rotate Array
    【LeetCode】190. Reverse Bits
    【LeetCode】191. Number of 1 Bits
    【C++】不要想当然使用resize
    【LeetCode】174. Dungeon Game
    【LeetCode】Largest Number
    【DeepLearning】Exercise:Convolution and Pooling
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7103186.html
Copyright © 2011-2022 走看看