题解 | #最长回文子串#

最长回文子串

https://www.nowcoder.com/practice/12e081cd10ee4794a2bd70c7d68f5507

使用双指针法进行 ~ 操作见代码注释。

import java.util.Scanner;

/*
    使用双指针的办法
    ---------------------------
    ...| perv | curr | next |...
    ---------------------------
         👆            👆
    <-- f_pointer    r_pinter -->
    
    使用一个指针遍历链表,遍历的过程中,检查当前指向元素与
    左、右以及指针位置的左右他们是否有回文的情况
	即 (perv curr), (curr next), (perv next)
    
    如果有回文的情况,设置两个新指针,分别指向回文的左右两个字符
    然后开始前进/后退,同时比较指向的两个元素的值是否存在回文

    直到不再回文了,记录回文次数与最大值做比较,取大的。
*/
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        char[] chars = s.toCharArray();
        int len = chars.length;
        // 最大回文
        int max = 0;
        // 这里注意越界条件判断
        for(int i = 1; i < len - 1; i++) {
            char perv = chars[i-1];
            char curr = chars[i];
            char next = chars[i+1];
            // 前进指针
            int f_pointer = 0;
            // 后退指针
            int r_pointer = 0;
            // 返回值
            int calv = 0;
            if(perv == curr) {
                // 当前字符串和它之前的回文
                f_pointer = i;
                r_pointer = i - 1;
                calv = calcVal(chars, len, f_pointer, r_pointer);
            } else if(curr == next) {
                // 当前字符串和它后边的回文
                f_pointer = i + 1;
                r_pointer = i;
                calv = calcVal(chars, len, f_pointer, r_pointer);
            } else if(perv == next) {
                // 当前字符串的前后回文
                f_pointer = i + 1;
                r_pointer = i - 1;
                calv = calcVal(chars, len, f_pointer, r_pointer);
                // 这里之所以 + 1 是因为要把 curr 字符也算在回文里面
                calv ++;
            }
            if(max < calv) max = calv;
        }
        System.out.println(max);
    }

    // 在元素中移动并且查找回文数值
    private static int calcVal(char[] chars, int length,int f_pointer, int r_pointer) {
        // 设置一个计数器
        int count = 0;
        /*
            只要前进和后退索引不到它们的阈值(前进不能超过 len -1,后进不能小于 0),
            并且 前进索引和后退索引的值,只要相同,就说明在回文,继续操作
        */
        while (f_pointer < length && r_pointer >= 0 && chars[f_pointer] == chars[r_pointer]) {
            // 步长为 2 因为每次两个指针各指一个元素
            count += 2;
            // 前进
            f_pointer ++;
            // 后退
            r_pointer --;
        }
        return count;
    }
}

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务