【算法训练-字符串 二】最长回文子串

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【最长回文子串】,使用【字符串】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。
【算法训练-字符串 二】最长回文子串_第1张图片

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

最长回文子串【MID】

一道中心扩展思想解决的MID题目

题干

【算法训练-字符串 二】最长回文子串_第2张图片

解题思路

【算法训练-字符串 二】最长回文子串_第3张图片

  1. 每个字符都可以尝试作为中心点看,会出现两种情况:可能是类似 aba 的字符串,也可能是类似 abba 的情况
  2. 只需要分别计算出以一个和两个字符作为中心点的子串,取出较大的长度即可
  3. 从left到right开始向两边扩散、比较,如果相等则继续扩散比较;如果不相等则剪枝,不用再继续扩散比较
  4. 计算每次比较的回文子串长度,取最大

代码实现

给出代码实现基本档案

基本数据结构字符串
辅助数据结构
算法迭代
技巧双指针、中心扩散法

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @return int整型
     */
    public String longestPalindrome(String s) {
        // 1 边界条件判断

        if (s.length() < 2) {
            return s;
        }
        // 2 初始化参数,结果参数的第一位存储起始位置,第二位存储长度
        int maxLength = 0;
        int[] result = new int[2];

        // 3
        for (int i = 0; i < s.length(); i++) {
            // 中心位置奇数情况下扩展结果
            int[] odd = centerSpread(s, i, i);
            // 中心位置偶数情况下扩展结果
            int[] even = centerSpread(s, i, i + 1);
            // 当前中心位置最大子串
            int[] curMax = odd[1] > even[1] ? odd : even;
            // 当前中心位置最大子串如果大于历史记录最大子串则暂存最大值及预期返回结果
            if (curMax[1] > maxLength) {
                maxLength = curMax[1];
                result = curMax;
            }
        }
        // 截取返回结果,本来如果起点是1,长度是2,那么结尾下标应该2(1+2-1),这里结尾为1+2=3,是因为3不会被计入,因为substring左闭右开区间,所以计算为(1+2-1+1(为开区间+1)=1+2=3)
        return s.substring(result[0], result[0] + result[1]);
    }

    // 扩散的核心方法
    public int[] centerSpread(String s, int left, int right) {
        // 双指针在边界内,且满足扩散条件
        while (left >= 0 && right <= s.length() - 1  &&
                s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        // 回文子串为左右指针开区间内的部分:right-1-(left+1)+1=right-left-1
        return new int[] {left + 1, right - left - 1};
    }
}

复杂度分析

时间复杂度 O(N^2):平均需要遍历每个结点作为中心点O(N),还需要从中心点向左右扩散比较O(N)
空间复杂度 O(1):只用到常量

你可能感兴趣的:(#,字符串,算法)