中心扩散法解回文串问题

	/**
	 * 中心扩散法解回文串问题
	 * @param s
	 * @return
	 */
	public String longestPalindrome(String s) {
		// 获取长度
		int len = s.length();
		// 如果长度是0或者1直接返回
		if(len == 0 || len == 1){
			return s;
		}
		// 将字符串转字符数组
		char[] chs = s.toCharArray();
		// 定义起始坐标
		int start = 0;
		// 定义最大长度
		int maxLen = 1;
		// 从0开始遍历
		for(int i=0;i<len;i++) {
			// 从i扩散获取最大长度
			int midLen = expand(chs, i, i);
			// 从i,i+1作为中心向外扩散获取最大长度
			int doubleLen = expand(chs, i, i+1);
			// 获取二者最大长度
			int tmpMax = Math.max(midLen, doubleLen);
			// 如果二者的最大长度 大于 变量最大长度,则替换相关数据
			if(tmpMax>maxLen){
				maxLen = tmpMax;
				// 起始下标取 以当前下标作为中心 的总长度为tmpMax的起始点作为下标
				// 如果 以i=5为单个中心点,3位最大长度,那么理论上其实下标应该为4  因为应该是 4 5 6 三个下标组成的字符串
				// 如果 以i=5, i+1=6 为双中心点, 那么tmpMax必为偶数,如4,那么其实下标应该为 4 5 6 7
				// 所以如果是奇数个字符组成的,其实start =i - tmpMax/2;也是对的,当然使用 start = i - (tmpMax-1)/2 也是对的,因为是向下取整
				// 但当时偶数时,因为i是左侧的点,那么其实应该少走一个点,也就是start = i - tmpMax/2 = 5-4/2=3就不对了,削弱1,就可以得到正确的下标
				// 所以这里统一用 i - (tmpMax-1)/2 作为其实下标
				start = i - (tmpMax-1) / 2;
			}
		}

		return new String(chs, start, maxLen);
	}

	private int expand(char[] chs, int start, int end) {
		// 以 start 和 end 为中心向两边扩散,当累加完之后不正确时,其实此时的数据是脏数据,所以在结果返回时,我们应该去掉2长度的脏数据
		// 也就是,原本start到end的长度应该为 end - start + 1 ,而此时因为是不符合要求的长度,所以,我们应该减掉2来 获取最近一次符合条件的长度
		// 因此结果返回为 end - start +1-2 = end - start - 1
		while(start>=0 && end<chs.length && chs[start]==chs[end]){
			start--;
			end++;
		}
		return end-start-1;
	}

遍历每个下标,每次以该下标为中心的向外扩展的最长奇数个字符的字符串

和以该下标及该下标的下一个下标为中心向外扩展的最长偶数个字符的字符串,

取最长一个,和当前结果变量作比较,如果是更长的长度,那么替换结果变量

最终获取最长的 回文 子串

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值