程序员笔试题---【最大回文子串】

本文探讨了多种求解字符串中最大回文子串的方法,包括蛮力法、改进后的统一处理方法及O(n)复杂度的高效算法,并附带实现代码。

最大的回文字串,相信大家都很熟悉了,类似的题目有过很多。

单纯的有求解字符串中的最大回文字串,例如:“abcgoogleaba”,最大的回文字串为goog,虽说aba也是回文但长度较短。

还有网易游戏考到的一道题:“abcgoogleaba”,如果是回文的话,当做一个整体输出,否则单个的输出,这个输出的格式为:a,b,c,goog,l,e,aba.

针对求最大的回文字串问题。有很多种方式,比如蛮力法。但是相信大家在笔试或者面试的时候,考官都会要求尽量的好的时间和空间复杂度。

因此我们需要寻找更好的办法。

第一、最大的回文字串

1、一般的做法,分为回文串是偶数个还是奇数个

就如上面的例子一样:abcgoogleaba,两个回文,一个是goog,另一个是:aba

#include "stdafx.h"
#include <iostream>
using namespace std;

int getMaxHuiWen(char * p,int len)
{
	int i=0,j=0;
	int max=0;
	int x,y;
	for(i=0;i<len;i++)
	{
		for(j=0;i-j>=0&&i+j<len;j++)//回文的字符个数为奇数
		{
			if(p[i-j]!=p[i+j])
				break;
			else
			{
				if(2*j+1>max)
				{
					max=2*j+1;
					x=i-j;
					y=i+j;
				}

			}
		}

		for(j=0;i-j>=0&&i+j+1<len;j++)//回文字符个数为偶数
		{
			if(p[i-j]!=p[i+j+1])
				break;
			else
			{
				if(2*j+2>max)
				{
					max=2*j+2;
					x=i-j;
					y=i+j+1;
				}

			}
		}
	}

	for(int k=x;k<=y;k++)//打印出回文
	{
		cout<<p[k];
	}
	return max;//返回最长回文的长度
}
int main(int argc, char* argv[])
{
	char *p="abcgooglrcabac";
	int len=strlen(p);
	int max=getMaxHuiWen(p,len);
	cout<<endl;
	cout<<max<<endl;
	return 0;
}


2、将偶数个奇数个统一起来

如何统一,这是个问题?

我们可以这样,在每个字符之间插入一个特殊的字符

比如上面的字符串:abcgoogleaba。可以进行这样的操作:#a#b#c#g#o#o#g#l#e#a#b#a#

这样回文的字串就都是奇数的情况,就不需要考虑偶数的情况。

int getMaxHuiWenChar(char *p,int len)
{
	int nLen=2*len+3;
	char *str =new char[nLen];
	int i=0;
	int max;
	int j=0,x,y;
	str[0]='$';
	str[1]='#';
	for(;i<len;i++)//精华就是这里啦
	{
		str[i*2+2]=p[i];
		str[i*2+3]='#';
	}
	str[nLen-1]=0;

	for(i=0;i<nLen;i++)
	{
		cout<<str[i];
	}
	cout<<endl;

	for(i=1;i<nLen;i++)
	{
		for(j=0;i-j>=0&&i+j<nLen;j++)
		{
			if(str[i-j]!=str[i+j])
				break;
			else
			{
				if(j>max)
				{
					max=j;
					x=i-j;
					y=i+j;
				}
			}
		}
	}

	for(int k=x+1;k<=y-1;k+=2)//打印出回文
	{
		cout<<str[k];
	}
	return max;
}

输入:abcgottoglrcabac

3、上面的做法的时间复杂度依然不是很理想的

下面我们用更好的点做法O(n)

int getMaxHuiWenCharP(char *s,int len)
{
	int nLen=2*len+3;
	char *str =new char[nLen];
	int i=0;
	int max=0;
	str[0]='$';
	str[1]='#';
	for(;i<len;i++)
	{
		str[i*2+2]=s[i];
		str[i*2+3]='#';
	}
	str[nLen-1]=0;
	int *p=new int[nLen];//定义一个用于标记的int数组

	for(i=1;i<nLen;i++)
	{
		cout<<str[i];
		p[i]=0;
	}
	cout<<endl;

	int id=0;
	for(i=1; i<nLen; i++)
    {
        if( max > i )
            p[i] = MIN( p[2*id-i], p[id]+id-i );//这里定义一个MIN的宏
        else
            p[i] = 1;
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
            NULL;
        if( p[i] + i > max )
        {
            max = p[i] + i;
            id = i;
        }
    }

	int mx=0;
	for(i=1;i<nLen;i++)
	{
		if(mx<p[i]-1)
			mx=p[i]-1;
	}
	return mx;
}

第二、网易游戏笔试题

根据上面提供的方式,大家先柔和下咯!

欢迎大家t提供更好的办法哈!
功能简介:- 按时间拆分与按镜头拆分:支持对素材列表批量按固定时长或自动检测镜头边界进行切段;生成规范命名的片段文件。- 混剪合成:可随机截取片段或截取片头,自动拼接片头/片段/片尾,完成一键合成输出。- 文本与特效:支持顶部/底部标题(字体/颜色/轮廓/字号/显示时长),裁剪、旋转、亮度/对比度/饱和度调整。- 画面叠加:支持 GIF 水印、画中画(透明度与随机位置)、背景图片和背景视频叠加。- 音频处理:支持手动选择背景音乐或目录随机挑选,音量可滑条或区间随机,自动混流到成片。- 输出与命名:支持分辨率与帧率覆盖,文件名库随机命名或时间戳命名,输出到指定目录。使用方法:- 基础混剪: 1) 在“步骤1:基础设置”添加视频素材,选择输出目录; 2) 根据需要启用“线性混剪”或“原创截取片头”;设置转场、交叉淡入淡出、特效、文字等; 3) 在“素材与配置”中按需启用片头/片尾、背景图片/视频、GIF水印、画中画、背景音乐; 4) 启用“文件名库”可随机生成输出文件名; 5) 点击“开始混剪”,等待进度完成,成片保存在输出目录。- 拆分工具: 1) 按时间拆分:设置“按时间拆分(秒)”,点击“开始按时间拆分”,批量生成固定时长片段; 2) 按镜头拆分:设置“镜头检测阈值”和“最短时长(秒)”,点击“开始按镜头拆分”,批量生成镜头片段。使用技巧:- 镜头拆分阈值越大越严格,画面变化不明显的素材适当提高阈值;最短时长设置可避免碎片化。- 线性混剪更适合多素材快速出片;原创截取片头适合单素材内容展示开场。- GIF 水印与画中画素材尽量选择透明背景或高分辨率源,使叠加效果更自然。- 文本标题可按“每行标题数”自动换行,配合轮廓色提升可读性;字体文件可自选系统或资源目录字体。- 背景音乐优先手动选择,未选择时可启用目录随机;音
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值