最长回文子串问题(java)

题目描述:给你一个字符串 s,找到 s 中最长的回文子串。
下面用中心扩展算法来解决这个问题,该算法的思路简单:遍历整个字符串,判断以单个字符或两个字符中间的夹缝为中心向两边拓展的字符串是否为回文串。判断的条件为左指针left和右指针right指向的字符是否相同。循环遍历比较回文串的长度,并记录最长回文子串的起始索引和结束索引。
java代码如下:

class Solution {
    public String longestPalindrome(String s) {
        // 若为null值或是空字符串,则返回""
        if (s == null || s.length() == 0) {
            return "";
        }
        int left = 0;
        int right = 0;
        // 遍历字符串
        for (int i = 0; i < s.length(); i++) {
        	// 子回文串长度为奇数的情况
            int len1 = expandAroundCenter(s, i, i);
            // 子回文串长度为偶数的情况
            int len2 = expandAroundCenter(s, i, i + 1);
            int len = Math.max(len1, len2);
            if (len > right - left) {
                // left = i = (len - 1) / 2中的len - 1是考虑到子回文串的长度是偶数的情况。
                left = i - (len - 1) / 2;
                right =  i + len / 2;
            }
        }
        // java中求子字符串为左闭右开
        return s.substring(left, right + 1);
    }

    public int expandAroundCenter(String s, int left, int right) {
        while(left >= 0 && right < s.length() && s.charAt(left) == s. charAt(right)) {
            left --;
            right ++;
        }
        return right - left + 1 - 2;
    }
}

说两个值得注意的细节:

  1. 在expandAroundCenter函数中返回的值为right - left + 1 - 2。其中right - left + 1是指针指向的子字符串的长度,减二是因为要去掉首尾两个元素。
  2. 当子回文串的长度为奇数时,left和right指针从中间元素向两边偏移的长度相同。而当子回文串的长度为偶数时,left指针向左偏移的长度要比right向右偏移的长度小1。故if (len > right - left) {
    left = i - (len - 1) / 2;
    right = i + len / 2;
    }

若有不正确的地方,忘请指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最长回文子串是指一个字符串最长回文子串。在 Java ,可以使用动态规划的方法来解决这个问题。 首先,定义一个二维数组 dp[][],其 dp[i][j] 表示字符串从索引 i 到 j 的子串是否是回文子串。初始化时,将所有 dp[i][i] 设置为 true,表示单个字符是回文子串。 然后,通过遍历字符串的长度和起始索引来更新 dp[][] 数组。具体的更新规则如下: 1. 当 s.charAt(i) == s.charAt(j) 且 (j - i <= 2 || dp[i+1][j-1] == true) 时,dp[i][j] 也为 true。这意味着如果当前字符相等,并且子串长度小于等于2或者去掉首尾字符后的子串是回文子串,则当前子串也是回文子串。 2. 在更新 dp[][] 数组的过程,记录最长回文子串的起始索引和长度。 以下是使用动态规划解决最长回文子串问题Java 代码示例: ```java public class LongestPalindromeSubstring { public static String longestPalindrome(String s) { int n = s.length(); boolean[][] dp = new boolean[n][n]; int maxLength = 1; int start = 0; // 初始化单个字符为回文子串 for (int i = 0; i < n; i++) { dp[i][i] = true; } // 更新 dp[][] 数组并记录最长回文子串的起始索引和长度 for (int len = 2; len <= n; len++) { for (int i = 0; i <= n - len; i++) { int j = i + len - 1; if (s.charAt(i) == s.charAt(j) && (len <= 2 || dp[i+1][j-1])) { dp[i][j] = true; if (len > maxLength) { maxLength = len; start = i; } } } } return s.substring(start, start + maxLength); } public static void main(String[] args) { String s = "babad"; String longestPalindrome = longestPalindrome(s); System.out.println("最长回文子串为: " + longestPalindrome); } } ``` 运行上述代码,输出结果为: ``` 最长回文子串为: bab ``` 以上就是使用动态规划解决最长回文子串问题Java 实现方法。希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值