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。



  • 相关阅读:
    [算法] 堆栈
    [刷题] PTA 02-线性结构3 Reversing Linked List
    java IO流 (八) RandomAccessFile的使用
    java IO流 (七) 对象流的使用
    java IO流 (六) 其它的流的使用
    java IO流 (五) 转换流的使用 以及编码集
    java IO流 (四) 缓冲流的使用
    java IO流 (三) 节点流(或文件流)
    java IO流 (二) IO流概述
    java IO流 (一) File类的使用
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7103186.html
Copyright © 2011-2022 走看看