LeetCode(5. 最长回文子串)

如题在这里插入图片描述起初想偷懒用dp,index为i处的最大回文串和包含i的最大回文串推导i+1的

	//暂时无法实现
	public static String longestPalindrome1(String s) {
		if (s.length() < 1) {
			return "";
		}
		char[] cs = s.toCharArray();
		List<int[][]> data = new ArrayList<>();
		int[][] data1 = { { 0, 0 }, { 0, 0 } };
		int flag = 0;
		int idex = -1;
		data.add(data1);
		for (int i = 1; i < s.length(); i++) {
			int[][] bdata = data.get(i - 1);
			int[][] datao = new int[2][2];
			datao[0][1] = i;
			datao[0][0]=-1;
			if (bdata[0][0] != 0 && cs[bdata[0][0] - 1] == cs[i]) {
				datao[0][0] = bdata[0][0] - 1;
			} else if (bdata[0][0]!=i-1&&s.substring(bdata[0][0], i - 1)
					.equals(i == s.length() ? s.substring(bdata[0][0] + 2) : s.substring(bdata[0][0] + 2, i + 1))) {
				datao[0][0] = bdata[0][0] + 1;
			} else if(i>1&&cs[i]==cs[i-2]) {
				datao[0][0]=i-2;
			}else {
				datao[0][0] = i;
			}
			if (cs[i] == cs[i - 1]) {// 缓存连等信息
				idex = idex==-1?i - 1:idex;
				if(flag==0) {
					datao[0][0] = datao[0][0]==-1?i - 1:(datao[0][0]<i - 1?datao[0][0]:i - 1);
				}else {
					datao[0][0]=datao[0][0]==-1?idex:(datao[0][0]<idex?datao[0][0]:idex);
				}
				flag = 1;				
			} else {
				flag = 0;
				idex=-1;
			}

			if (datao[0][1] - datao[0][0] > bdata[1][1] - bdata[1][0]) {// 当前位自身回文大于前序最长回文
				datao[1] = datao[0];// 当前最长回文就是当前位自身回文
			} else {
				datao[1] = bdata[1];// 当前最长回文仍未前一位最长回文
			}
			data.add(datao);
		}
		int[] is = data.get(data.size() - 1)[1];
		return is[1] == s.length() - 1 ? s.substring(is[0]) : s.substring(is[0], is[1] + 1);
	}

但是对于由包含i的最大回文串推导i+1时仍未完成所有可能性的检索,目前是无法应对12100121001210012100121的情况对于完整重复串01210的检索只能做到应对偶数个的情况
只能老老实实检索以某个点为中心的回文串了

public static String longestPalindrome(String s) {
		if (s.length() < 1) {
			return "";
		}
		char []cs =s.toCharArray();
		int li=0;
		int ri=0;
		for(int i=1;i<s.length();i++) {
			int m=1;//发散范围
			int len=1;//回文串长度
			if(cs[i]==cs[i-1]) {//连续相同字符
				if(li==ri){
					li=i-1;
					ri=i;
					len=2;
				}
				while(i+m<s.length()&&i-m>0){//检索该相同字符两边字符
					if(cs[i+m]==cs[i-1-m]){//回文范围加1
						if(m*2+2>len){//更长的回文串
							len=2*m+2;
							if(len>ri-li){
								li=i-m-1;
								ri=i+m;
							}
						}
						m++;//发散范围+1
					}else{
						break;//不构成回文则退出
					}
				}
				m=1;//记得还原
			}
			while(i+m<s.length()&&i-m>=0){
				if(cs[i+m]==cs[i-m]) {//检索两边字符是否相等
					if(2*m+1>len){
						len=2*m+1;
						if(len>ri-li) {
							li = i - m;
							ri = i + m;
						}
					}
					m++;
				}else{
					break;
				}
			}
		}
		return ri==s.length()-1?s.substring(li):s.substring(li,ri+1);
	}

在这里插入图片描述
还是想找一个一次遍历就实现的算法,貌似题解中有,等理解了后续添加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值