【leetcode】5.Longest Palindromic Substring(c语言)

Description:

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example1:

Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.

Example2:

Input: “cbbd”
Output: “bb”

[ 题目链接 ]

测试点检查:
1.输入空串"": 输出也要是空串
2.输入"ac" :输出"a"
3.输入"a" : 输出"a"
4.字符串中包含"aaaa"
5.字符串中包含"sooos"

解题思路:
解法一:
我将回文串分为三种:
第一种是对称式回文串,比如:acddca
第二种是重复式的,比如:aaaaa
第三种是夹心饼干使的:acbca
针对这三种情况来分析

解法二:
马拉车(Maracher)算法
这道题用c语言的马拉车算法反而更耗时
因为需要频繁地申请内存
可能其他语言会更加高效
(JAVA效果比较好)


提交代码:
解法一:

char* longestPalindrome(char* s)
{
	int i, j;
	int max_len = 0, pos = 0, string_len = 0;

	for (i = 0; s[i] != '\0'; i++)
	{
		int current_len = 0;

		if (s[i] == s[i + 1])
		{
			//重复式回文串:aaaa...
			char c = s[i];
			j = i + 1;
			while (s[j] == c)
				j++;
			current_len = j - i;

			//对称回文串cabbac
			for (j = i - 1; j >= 0 && s[2 * i - j + 1] != '\0'; j--)
				if (s[j] != s[2 * i - j + 1])
					break;

			if (2 * (i - j) > current_len)
				current_len = 2 * (i - j);
		}

		//如果当前回文串长度大于最大回文串长度,更新
		if (current_len > max_len)
		{
			pos = j + 1;
			max_len = current_len;
		}

		current_len = 0;
		//夹心饼干回文串:acbca
		if (s[i] == s[i + 2])
		{
			for (j = i - 1; j >= 0 && s[2 * i - j + 2] != '\0'; j--)
				if (s[j] != s[2 * i - j + 2])
					break;

			current_len = 2 * i - 2 * j + 1;;
		}

		//如果当前回文串长度大于最大回文串长度,更新
		/*更新2次的原因是,可能子字符串即满足对称回文串也满足夹心饼干
		回文串,所以更新两次,选取更长的*、
		if (current_len > max_len)
		{
			pos = j + 1;
			max_len = current_len;
		}
	}

	//创建新的最长回文串子串
	//如果最大长度还是0的话可能是空串或者没有回文串
	if (max_len == 0)
	{
		//空串
		if (s[0] == '\0')	return s;

		char* substring = (char*)malloc(2 * sizeof(char));
		substring[0] = s[0];
		substring[1] = '\0';
		return substring;
	}
	else
	{
		char* substring = (char*)malloc((max_len + 1) * sizeof(char));
		for (i = pos, j = 0; i < (pos + max_len); i++, j++)
			substring[j] = s[i];
		substring[j] = '\0';
		//printf("%s\n", substring);

		return substring;
	}
}

运行结果:
【leetcode】5.Longest Palindromic Substring(c语言)_第1张图片


解法二:马拉车

char* longestPalindrome(char* s)
{
	int i, j, k, string_len = 0;

	//计算数组长度
	for (i = 0; s[i] != '\0'; i++)
		string_len++;

	//创建新的马拉车数组,数组长度是2*string_len+3
	char* mana_string = (char *)malloc((2 * string_len + 3) * sizeof(char));
	mana_string[0] = '$';

	for (i = 0, k = 1; i < string_len; i++, k++)
	{
		mana_string[k++] = '#';
		mana_string[k] = s[i];
	}
	mana_string[k++] = '#';
	mana_string[k] = '\0';

	printf("%s", mana_string);

	//创建回文半径数组radius[],数组长度是2*string_len+1
	int *radius = (int *)malloc((2 * string_len + 1) * sizeof(int));
	int max_right = 2, max_center = 1, max_radius = 1;
	radius[0] = 0;
	radius[1] = 1;

	for (i = 2; mana_string[i] != '\0'; i++)
	{

		if (max_right - i > radius[2 * max_center - i])
			radius[i] = radius[2 * max_center - i];
		else
		{
			radius[i] = 1;   //可再编辑?
			while (mana_string[i + radius[i]] == mana_string[i - radius[i]])
				radius[i]++;
			if (radius[i] >= max_radius)
			{
				max_radius = radius[i];
				max_center = i;
				max_right = i + radius[i];
			}
		}
	}

	//创建最长回文串字符串
	int substring_len = (2 * max_radius - 1) / 2;
	char* substring = (char*)malloc(substring_len * sizeof(int));

	int start = (max_center - max_radius + 1) / 2;
	int end = (max_center + max_radius - 3) / 2;
	for (i = start, j = 0; i <= end; i++, j++)
		substring[j] = s[i];
	substring[j] = '\0';
	printf("%s", substring);

	return substring;
}

运行结果:
【leetcode】5.Longest Palindromic Substring(c语言)_第2张图片

解法二:马拉车(JAVA实现)

class Solution {
    public String longestPalindrome(String s) {
    	char[] str=new char[2*s.length()+2];
    	str[0]='$';
    	for(int i=0;i<s.length();i++) {
    		str[2*i+1]='#';
    		str[2*i+2]=s.charAt(i);
    	}str[str.length-1]='#';
    	
    	// 	manacher
    	int center=1,p,maxCenter=0;
    	int[] radius=new int[2*s.length()+2];
    	radius[0]=1;radius[1]=1;
    	for(p=2;p<str.length;p++) {
    		if(p>=center+radius[center]) {
    			// the p is out of the range of center
    			radius[p]=1;
    			for(int i=p+1;i<str.length&&2*p-i>=0&&str[i]==str[2*p-i];i++)
    				radius[p]++;
    			center=p;
    			if(radius[center]>radius[maxCenter])		maxCenter=p;
    		}else if(p+radius[2*center-p]<center+radius[center]-1) {
    			// the p is in the range of center
    			radius[p]=radius[2*center-p];
    		}else {
    			// the p is in the range of center, but the range of p can be farther
    			radius[p]=Math.max(center+radius[center]-p,1);
    			for(int i=center+radius[center];i<str.length&&2*p-i>=0&&str[i]==str[2*p-i];i++)
    				radius[p]++;
    			center=p;
    			if(radius[center]>radius[maxCenter])		maxCenter=p;
    		}
    	}
    	
    	return s.substring((maxCenter-radius[maxCenter])/2,(maxCenter+radius[maxCenter]-2)/2);
    	
    	
    }
}

运行结果:
【leetcode】5.Longest Palindromic Substring(c语言)_第3张图片

你可能感兴趣的:(leetcode)