leetcode[Longest Palindromic Substring]//待整理多种解法

本文介绍了一种高效算法用于找出给定字符串中的最长回文子串。通过一次循环结合回文特性,避免了传统双层循环所带来的超时问题。算法区分奇偶情况,仅需遍历字符串长度两倍的次数即可找到最长回文子串。

错误解法(遇到很长的字符串时会超时):

class Solution {
	private boolean isPalindrome(StringBuilder s){
		int i = 0;
		int j = s.length() - 1;
		while(i <= j){
			if(s.charAt(i) != s.charAt(j))
				return false;
			i++;
			j--;
		}
		
		return true;
	}
	
    public String longestPalindrome(String s) {
        //假设回文字符串的长度由大大小,自己指定一个尺度k,来判断是否存在长度为k的回文字符串
    	int k = s.length();
    	while(k >= 2){
    		StringBuilder sb = new StringBuilder(s.substring(0, 0 + k));
    		//System.out.println(k + "  " + sb);//
    		if(isPalindrome(sb))
    			return sb.toString();
    		for(int i = k; i < s.length(); i++){//有了尺度k,就可以借用slide window的想法,这里i就从k到结尾,代表可以移动的距离
    			sb.deleteCharAt(0);
    			sb.append(s.charAt(i));
    			//System.out.println(k + "  " + sb);//
    			if(isPalindrome(sb))
        			return sb.toString();
    		}
    		k--;
    	}
    	
    	return s.length() != 0 ? s.charAt(0)+"" : "";//一定存在长度为1的,那么就返回第一次出现的
    }
}

解法一:

class Solution {
	//既然要求出一个字符串中最长的回文子串,通过两次循环可以解决(因为两次循环就可以求出所有的子串,再依次判断即可,但是长度过大时会超时)
	//那么用一次循环,根据回文字符串的特点,要么是abba的形式,要么是abcba的形式,即分奇偶,那么就根据回文字符串的生成
	//遍历字符串s,对于每一个字符,判断其左右所能生成的最大长度的子串,这样就不用求出所有的子串了,只用求s.length()*2个子串,而且中途还可以撤出
	//比起上面博客所写的超时的错误解法,设子串长度为k,从s.length开始判断,每次的长度k要判断n-k个子串(利用slide window),就容易超时
	//s.length()*2 是因为分奇偶判断 abba 还是abcba
	
	int start = 0;
	int max = 0;
	
	//计算字符串s中第i,j个位置的字符往左往右所能生成的最长的回文子串(子串就是连续的)的长度
	private int maxIsPalindrom(String s, int i, int j){//i=j时就代表是奇数aba,j = i+1时就代表是偶数abba
		
		/*while(i >= 0 && j < s.length()){
			if(s.charAt(i) == s.charAt(j)){
				i--;
				j++;
			}
			else{
				break;
			}
		}
		
		return j - i + 1;*/
		
		//如果只是求出最长回文子串的长度,用上面注释的就可以了,但是要求出具体的子串,就要记录位置
		while(i >= 0 && j < s.length()){
			if(s.charAt(i) == s.charAt(j)){
				i--;
				j++;
			}
			else{
				break;
			}
		}
		
		if(j - i - 1 > max){
			max = j - i - 1;//因为条件不满足时i已经多减了1,j已经多加了1,所以这里是j - i - 1
			start = i + 1;//因为条件不满足时i已经多减了1,所以这里是i+1
		}
		
		return max;
	}
	
	public String longestPalindrome(String s) {
		if(s.length() < 2){//空串和只有一个字符的直接返回就好
			return s;
		}
		
		for(int i = 0; i < s.length(); i++){
			maxIsPalindrom(s, i, i);//aba
			maxIsPalindrom(s, i, i + 1);//abba
		}
		
		return s.substring(start, start + max);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值