最长回文子串(力扣5)

题目描述

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。


示例 2:

输入: "cbbd"
输出: "bb"

解题思路

利用回文字符串的特点:正着读和反着读都是一样的,所以首先把s反转,利用i和j控制左右边界,不断从s中截取子字符串,这时需要理解反转字符串中对应i和j的关系,同时从反转字符串中进行截取,进行比较。max表示当前字符串的长度,如果新的子字符串长度大于max才将替换。

public static String longestPalindrome(String s) {
		int len = s.length();
		String str = "";
		String reverse = new StringBuffer(s).reverse().toString();
		int max = -1;
		if (len <= 1)
			return s;
		for (int i = 0; i < len; i++) {
			for (int j = len; j > i; j--) {
				String sub1 = s.substring(i, j);
				String sub2 = reverse.substring(s.length() - j, reverse.length() - i);
				if (sub2.equals(sub1)) {
					if (j - i > max) {
						str = sub1;
						max = j - i;
					}
				}
			}
		}
		return str;
	}

本以为可以痛痛快快的通过测试,没想到居然超时了!!!!

 现在对上面代码进行优化,优化1:因为j是从后向前循环的,所以当j-i>max时,替换当前str时,直接break,因为j是不断的变小,所以就算以后出现了回文字符串,也会比当前保存的回文字符串短。优化2:当len-i< max时,应该直接返回str,因为以后的子字符串长度必然没有str的长度长。

public static String longestPalindrome(String s) {
		int len = s.length();
		String str = "";
		String reverse = new StringBuffer(s).reverse().toString();
		int max = -1;
		if (len <= 1)
			return s;
		for (int i = 0; i < len; i++) {
			if (len - i < max)
				return str;
			for (int j = len; j > i; j--) {
				String sub1 = s.substring(i, j);
				String sub2 = reverse.substring(s.length() - j, reverse.length() - i);
				if (sub2.equals(sub1)) {
					if (j - i > max) {
						str = sub1;
						max = j - i;
						break;
					}
				}
			}
		}
		return str;
	}

怀着忐忑的心情,再次测试用例,这次勉强通过了。看到执行结果看到速度还是可以的。

本题还有很多方法可以实现:暴力破解、动态规划,我这次采用的是较为简单的思路,希望有大佬可以指出还有什么优化方式。

猜你喜欢

转载自blog.csdn.net/qq_44313091/article/details/107790366