5. 最长回文子串 JAVA版

5. 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
回文的意思是正着念和倒着念一样,如:上海自来水来自海上
示例 1:

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

输入: “cbbd”
输出: “bb”

方法一:暴力循环法

因为回文满足对称性,所以我们可以对每次截取的字符串,设置两个指针,对头部和尾部同时进行判断,当出现头部和尾部不匹配的情况,则不是回文串,若为全部匹配没有发现,则为回文串。
每次对测试成功的串进行长度统计,最终返回最长的一个回文串长度。

public String longestPalindrome(String s) {
		  int i,j;
		  String end = "";
		  int result = 0;
		  String a;
		  if(s.length() == 1)return s;
		  else {
		  	for (i = 0;i<s.length();i++) {
		  		for (j = i+1;j<=s.length();j++) {
		  			a = s.substring(i, j);///不包含??
		  			if (test(a)&&a.length()>result) {
		  				result = a.length();
		  				end = a;
		  			}
		  		}
		  	}
		  	return end;
		  }
	    }
	  public boolean test(String s) {
		  int a = s.length();
		  int g = 0,key = 0;
		  for (g = 0;g < a/2;g++) {
			  if (s.charAt(g)!=s.charAt(a-g-1))return false;
		  }
		  return true;
    }

因为使用了三重循环,所以时间复杂度为 O(n³),空间复杂度为O(1).

运行结果:

超出时间限制
输入:

"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

代码优化的思路就是:将substring更换为两根指针可能会解决问题。以后留时间解决。

方法二:中心扩展算法

同样的,回文满足对称性,原来我们是对子串进行单独处理判断,现在换一种思路,每次选择一个中心对称轴,对中心对称轴两边进行扩展,最后算出长度,接下来就是对end 和star 的更新,最后由star 和 end来确认字符串的起始和结束位置

	public int findcentrol(int left,int right,String s) {
		int L = left;
		int R = right;
		while(L>=0&&R<s.length()&&s.charAt(L)==s.charAt(R)) {
			L--;
			R++;
		}
		int length = R-L-1;
		return length;
	}
	public String solution(String s) {
		if (s.length()<1||s== null)return"";
		else {
			int i;
			int result,start = 0,end= 0;
			for (i = 0;i<s.length();i++) {
				int length1 = findcentrol(i, i, s);////判断在一个字符为中心时候的回文长度类似于'aba'
				int length2 = findcentrol(i, i+1, s);////判断在两个字符为中心时候的回文长度,类似于'abba'
				result = Math.max(length1, length2);
				if (result>end-start) {
					end = i+result/2;
					start = i-(result-1)/2;
				}
			}
			return s.substring(start,end+1);
			
		}
	}

运行结果

103 / 103 个通过测试用例
状态:通过
执行用时:33 ms
内存消耗:37.9 MB

其他还有三种方法本次暂时不加赘述,下次将会补充。

遇到的问题

  1. substring(i,j)代表截取的字符串位置包含从i位到j-1位,不包含j位。
发布了9 篇原创文章 · 获赞 0 · 访问量 67

猜你喜欢

转载自blog.csdn.net/weixin_44575373/article/details/104669065