5. Longest Palindromic Substring

  • 题目描述

  • 题目思路1

这道题LeetCode上的标签是Dynamic programming,即动态规划,第一个思路就是用动态规划来解。

首先维护一个二维数组dp[j][i]。这个动态数组表示[j, i]之间是否有回文。当j = i时,只有一个字符,肯定是回文,当 j + 1 = i 时,说明是相邻的字符,那么需要比较s[j]和s[i]是否相等,如果i - j >= 2时,除了判断s[i]和s[j]之外,还必须判断dp[j+1][i-1]是否为真,如果为真,就是回文串。

以babad为例

当i = 4,j = 0时,i - j > 2,首先要判断s[i] 和s[j]是否相等,其次,还要判断j和i之间的a b a 是否为回文串,如何判断a b a 是否为回文串,就是要看dp[][]数组,看dp数组的[j+1][i-1]是否为真。

  • C++实现
class Solution 
{
public:
	string longestPalindrome(string s) 
	{
		int len = 1;  //存储当前的回文长度
		int left = 0;  //回文长度的起始位置
		int n = s.length();
		int **dp;
		dp = new int *[n];
		for (int i = 0;i < n;i++)
		{
			dp[i] = new int[n];
		}

		for (int i = 0;i < n;i++)
		{
			dp[i][i] = 1;
			for (int j = 0;j < i;j++)
			{
				dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j+1][i-1]));
				
				if (dp[j][i] && len < i - j + 1)
				{
					len = i - j + 1;
					left = j;
				}
			}
		}
		return s.substr(left,len);
	}
};

用C++实现的效率太慢了,参考LeetCode给出的数据

  • 第二次刷

  • 递归写法

    判断字符串str是否是回文串

  class Solution {
  public:
      bool is(string s,int i,int j)
      {
          if(j-i==0)
              return true;
          if(j-i==1)
          {
              if(s[i]==s[j])
                  return true;
              else
                  return false;
          }
          
          if(s[i]==s[j] && is(s,i+1,j-1))
              return true;
          else
              return false;
      }
      
      string longestPalindrome(string s) {
          int len=s.length();
          string temp;
          string result;
          int max=0;
          
          for(int i=0;i<len;i++)
          {
              for(int j=i;j<len;j++)
              {
                  if(is(s,i,j))
                  {
                      if(max<j-i+1)
                      {
                          result.replace(0,result.length(),s.substr(i,j-i+1));
                          max=j-i+1;
                      }
                  }
              }
          }
          return result;
      }
  };
  • 由动态规划改为递归写法
class Solution
{
public:
	string longestPalindrome(string s)
	{
		int length = s.length();
		int strmax = 0;
		int left = 0;
		int right = 0;

		vector<vector<bool>> dp(length, vector<bool>(length));

		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				dp[i][j] = true;
			}
		}

		for (int i = 0; i < length - 1; i++)
		{
			dp[i][i + 1] = (s[i] == s[i + 1]);
		}

		//填充dp数组中其他空余的部分
		for (int i = length - 3; i >= 0; i--)
		{
			for (int j = length - 1; j >= i + 2; j--)
			{
				dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
			}
		}

		//检查dp数组中为true的部分 并且找出最大值
		for (int i = 0; i < length; i++)
		{
			for (int j = i; j < length; j++)
			{
				if (dp[i][j])
				{
					if (strmax < j - i + 1)
					{
						left = i;
						right = j;
						strmax = j - i + 1;
					}
				}
			}
		}

		return s.substr(left, right - left + 1);
	}
};

从运行结果来看,即便是这个DP版本的程序,也有很多可以改进的地方。

1 《Leetcode-5-Longest Palindromic Substring》 http://zyy1217.com/2017/04/09/leetcode5/

posted @ 2019-09-12 09:26  尚修能的技术博客  阅读(105)  评论(0编辑  收藏  举报