leetcode05最长回文子串

小编 2026-07-01 阅读:1536 评论:0
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 看到一道题没什...

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

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

看到一道题没什么思路,首推暴力法,无脑暴力,写出来再说

  • 暴力法,找出每一个子串,并判断是否为回文字符串,注意边界问题
  • 定义一个数组记录找到的最长回文字符串的左右边界
  • 暴力法的时间复杂度为O(n^3),空间复杂度O(1)
public String longestPalindrome(String s) {
		int[] bound = new int[2];
		int n = s.length(), res = 0;
		for (int i = 0; i != n; i++) {
			for (int j = 0; j != n; j++) {
				// 判断的此子串是否为回文子串
				boolean f = ifPalindrome(s, i, j);
				if (f && (j - i + 1) > res) {
					res = j - i + 1;
					bound[0] = i;
					bound[1] = j + 1;
				}
			}
		}
		return s.substring(bound[0], bound[1]);

中心法,遍历字符串,把每个字符当做中心,根据条件往两边扩,记录最大值 奇数数组好扩 “aba” 偶数数组不好扩 “abba”,找不到中心,所以要变形

  • \"#a#b#b#a#\"这样的话中心是第三个# 只记左边长度是4,等价总长 看
  • 一下扩展奇数数组\"aba\", “#a#b#a#”,b为中心,左边长度是3
  • 变形需要用到StringBuilder吧?
  • 中心法时间复杂度O(n^2) 空间复杂度O(n)
public String longestPalindrome_1(String s) {
		if (s == null || s.length() < 2)
			return s;
		int n = s.length(), res = 0;
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i != s.length(); i++) {
			sb.append(\"#\" + s.charAt(i));
		}
		sb.append(\"#\");
		int index = 0;
		s = sb.toString();// 变形后
		for (int i = 0; i != s.length(); i++) {
			// 这里判断能不能往外扩的最长串,返回值要
			int len = caculateLong(s, i);
			// 更新
			if (len > res) {
				res = len;
				index = i;
			}
		}
		/*
		 * substring(a,b); 截取字符串上的距离,左闭右开 [a,b) replace(rex,\"要替换的值\"); 替换字符串中某些字符
		 */
		return s.substring(index - res, index + res + 1).replace(\"#\", \"\");
	}
	



public int caculateLong(String s, int i) {// 时间复杂度 O(n)
		int n = s.length(), l = i - 1, r = i + 1, res = 0;
		while (l >= 0 && r < n) {// 最大可以扩到[0,n-1]
			if (s.charAt(l--) == s.charAt(r++)) {
				res++;
			} else
				break;
		}
		return res;
	}

回文中心新解,不用对s进行操作,遍历到i时,考虑i是回文中心(奇数) [i,i+1]的中心为回文中心分别考虑这两种情况,得到各自的回文长度,两者中较大的则是当前i位置能求得的最大回文长度

  • 奇数 “aba”,有回文中心b ,偶数 “abba” 没有回文中心 奇数:把[i,i]传进函数 特殊处理偶数,把[i,i+1]传进判断函数里
  • 1.若s[i]==s[i+1],则进入2,否则退出判断
  • 2.若s[i-1]==s[i+2],则进入3,
  • 最大判断至 s[0] == s[n-1] (整个字符串都为回文字符串), 最后返回当前回文中心回文字符串的长度:r-l-1

无需扩展

public String longestPalindrome_2(String s) {
		if (s == null || s.length() < 1) {
		return \"\";
	}
	int e = 0;
	int start = 0;
	for (int i = 0; i != s.length(); i++) {
		// 1.考虑i为回文中心
		int len1 = longPalindrom(s, i, i);
		// 2.考虑[i,i+1]之间为回文中心
		int len2 = longPalindrom(s, i, i + 1);
		int len = Math.max(len1, len2); // 最小回文子串也是其自身 1
		if (len > e - start) {// 这里也要抠,本来[e,s]的长度为s-e+1,既然len>e-s,则len最小也等于s-e+1,可以更新一波
			start = i - (len - 1) / 2;// 举例:\"aba\",b为回文中心,len = 3 , start = 1 - (3-1)/2=0,
			e = i + len / 2;// i/2==(i+1)/2,这里长度是奇数和偶数不影响 end = 1 + 3/2 =2
		}
	}
	return s.substring(start, e + 1);
}

动态规划时间复杂度为O(N2),空间复杂度为O(N^2),

  • 动态规划解法 举例:s=“xabcbay”,其子串\"abcba\"是回文子串,若x==y,则该串为回文子串
  • dp[i][j]:表示字符串[i,j]是否为回文字符串
  • 动态递推式:dp[i][j] = dp[i+1][j-1] && s[i]==s[j]
  • 最大判断至 s[0] == s[n-1] (整个字符串都为回文字符串), 最后返回当前回文中心回文字符串的长度:r-l-1
public String longestPalindrome_3(String s) {

		// 先填二维数组能填的部分,第一行dp[0][j]
		if (s == null || s.length() < 1)
			return \"\";
		int n = s.length();
		boolean[][] dp = new boolean[n][n];// 默认复制为false
		int res = 1, start = 0, end = 0;
		// 初始化,任意一个字符i,[i,i]是回文子串, 如果s[i]==s[i+1],则[i,i+1]是回文子串
		for (int i = 0; i != n; i++) {
			for (int j = i; j != n; j++) {
				if (i == j) {
					dp[i][j] = true;
				}
				if ((i + 1) != n && s.charAt(i) == s.charAt(i + 1)) {
					dp[i][i + 1] = true;
				}
			}
		}
		// 数组要从下往上填,因为dp[i][j] 根据 dp[i+1][j-1]来推
		for (int i = n - 2; i >= 0; i--) {
			for (int j = 0; j < n; j++) {
				if (i < n - 1 && j >= 1) {
					if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]) {
						dp[i][j] = true;
					}
				}
			}
		}
		for (int k = 0; k != n; k++) {
			for (int j = n - 1; j >= k; j--) {
				if (dp[k][j] && res < (j - k + 1)) {
					res = j - k + 1;
					start = k;
					end = j;
				}
			}
		}
		return s.substring(start, end + 1);
	}

总结:对于数组或者字符串求子串的问题,注意不是子序列,这类题可以使用暴力法找到所有的子串,逐一比较,求得解,当然这种解法是不能通过oj的,复杂度太高。可以往动态规划或者滑动窗口上面想。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表