算法设计题--最长回文子串

最长回文子串
难易程度:中级

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

示例 1:

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

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

解释一下,什么是回文子串

例如:babab的回文子串就是bab,因为从第一个字符读到最后一个字符的字符顺序,和从最后一个字符读到第一个字符的字符顺序是一致的,都是bab,因此是回文子串。

思路:

1 非算法思路:

首先,我想到的思路是,先将字符串给分割开,例如:
b, ba,bab,baba,babad,
a,ab,aba,abad,
b,ba,bad,
a,ad,
b
分割之后,可以看到符合要求的有,bab和aba,接下来,我们对分割开找到的回文串找找特征,不管是偶数长度的回文串还是奇数长度的回文串,他们的第1位和最后一位相等,第二位和倒数第二位相等,以此类推。奇数长度特殊的一点就是中位数位置的字符没有与之相等的字符和它匹配。但是不影响我们分析。

定义int i=0,int j=n-1;
其中n=字符串的长度,i++推进字符数组向前进,j-- 推进字符数组向后退,然后i位置的字符和j位置的字符依次相比较。用while(i<j)来保证不会出现交叉。
话不多说,上代码:

我的思路比较简单,类似暴力破解

import java.util.*;
import java.util.Random;
public class M1 {
	    public static void main(String[] args) {
	    	Scanner in = new Scanner(System.in);
		  	String str = in.nextLine();
		 	int len = str.length();//获取字符串长度
		  	ArrayList<String> list = new ArrayList<>();
		  	for(int i = 0;i<=len;i++) {
	   			for(int j = len;j>i;j--) {
	    				list.add(str.substring(i, j));//加入分割后的字符串
	  		 	}
	 		}
		
		  
	  		for(String compare:list) {
	  			int n=compare.length();
	    		 char s[]=compare.toCharArray();
	    	     int i=0,j=n-1;
	    	     int sum=0;
	  			while(i<j) {
	    	    	 if(s[i]==s[j]) {
	    	    		 i++;
	    	    		 j--;
	    	    		 sum++;//进行计数,来检验是否全都比较一次了
	    	    	 }
	    	    	 else {
	    	    		 break;
	    	    	 }
	   			}
	  			if(sum==n/2&&sum!=0) {//如果全都检验一次了,就打印出来
	  				System.out.println(compare);
	  				break;//这里是只要有一个满足了,就可以跳出来了
	  			}
	 		}
	 		 if(str.length()==1) {
	  			System.out.println(str);
	  			}
	 	}
}

实现截图:

在这里插入图片描述

2 算法思路:

在这里插入图片描述
在这里插入图片描述

代码:
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        String ans = "";
        for (int l = 0; l < n; ++l) {
            for (int i = 0; i + l < n; ++i) {
                int j = i + l;
                if (l == 0) {
                    dp[i][j] = true;
                } else if (l == 1) {
                    dp[i][j] = (s.charAt(i) == s.charAt(j));
                } else {
                    dp[i][j] = (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]);
                }
                if (dp[i][j] && l + 1 > ans.length()) {
                    ans = s.substring(i, i + l + 1);
                }
            }
        }
        return ans;
    }
}


思路来源:力扣(LeetCode)

算法之路任重而道远啊,难!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值