Leetcode 字符串模板

KMP

java 复制代码
next数组
// next[i]:模式串 s[0..i] 的「最长相等前后缀」长度
int[] buildNext(String s) {
    int n = s.length();
    int[] next = new int[n];
    // next[0] = 0,单个字符没有真前后缀
    for (int i = 1, j = 0; i < n; i++) {   // j 是当前最长相等前后缀长度
        // 不相等就回退 j,直到能接上或 j=0
        while (j > 0 && s.charAt(i) != s.charAt(j)) j = next[j - 1];
        if (s.charAt(i) == s.charAt(j)) j++;  // 相等则延长
        next[i] = j;
    }
    return next;
}




KMP匹配
int strStr(String haystack, String needle) {
    int n = haystack.length(), m = needle.length();
    if (m == 0) return 0;
    int[] next = buildNext(needle);
    for (int i = 0, j = 0; i < n; i++) {   // i 遍历主串(永不回退)
        // 失配:把模式串指针 j 按 next 回退
        while (j > 0 && haystack.charAt(i) != needle.charAt(j)) j = next[j - 1];
        if (haystack.charAt(i) == needle.charAt(j)) j++;
        if (j == m) return i - m + 1;      // 匹配成功,返回起点下标
    }
    return -1;
}

回文

java 复制代码
中心扩展
String longestPalindrome(String s) {
    if (s == null || s.length() < 1) return "";
    int start = 0, maxLen = 0;
    for (int i = 0; i < s.length(); i++) {
        int len1 = expand(s, i, i);       // 奇数长度:以 i 为中心
        int len2 = expand(s, i, i + 1);   // 偶数长度:以 i,i+1 为中心
        int len = Math.max(len1, len2);
        if (len > maxLen) {
            maxLen = len;
            start = i - (len - 1) / 2;    // 由中心和长度反推起点
        }
    }
    return s.substring(start, start + maxLen);
}

// 从中心向两边扩,返回回文长度
int expand(String s, int l, int r) {
    while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { l--; r++; }
    return r - l - 1;   // 退出时多走了一步,故 -1
}
区间DP求回文
// dp[i][j]:s[i..j] 内最长回文子序列长度。按区间长度从小到大
int longestPalindromeSubseq(String s) {
    int n = s.length();
    int[][] dp = new int[n][n];
    for (int i = n - 1; i >= 0; i--) {    // i 倒序,保证算 [i][j] 时 [i+1][*] 已就绪
        dp[i][i] = 1;
        for (int j = i + 1; j < n; j++) {
            if (s.charAt(i) == s.charAt(j))
                dp[i][j] = dp[i+1][j-1] + 2;   // 两端相等,收缩
            else
                dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]); // 丢掉一端
        }
    }
    return dp[0][n-1];
}

Manacher
// 插入分隔符 '#' 把奇偶统一成奇数长度,维护最右回文边界 R 和其中心 C
String preProcess(String s) {
    StringBuilder sb = new StringBuilder("^#");
    for (char c : s.toCharArray()) sb.append(c).append('#');
    sb.append("$");
    return sb.toString();
}
// p[i] 记录以 i 为中心的回文半径,核心:
// if (i < R) p[i] = Math.min(R - i, p[2*C - i]);  // 利用对称性复用
// 再尝试向两边扩展,更新 C、R
相关推荐
SimonKing16 小时前
零配置也能白嫖前沿大模型!dsh-our-free-model插件真香警告
java·后端·程序员
nice_lcj52016 小时前
【从零理解 Spring AI · 15】让检索更准:先宽召回,再精排序
java·后端·rag·spring ai·ai应用开发·检索优化·重排序
zaizai100716 小时前
算法(左程云)1
数据结构
小南家的青蛙17 小时前
微服务体系下DevOps运维岗位面试方案设计
运维·面试·职场和发展·devops
杨凯凡17 小时前
Spring Boot 链路追踪实战:Micrometer、TraceId 与异步线程上下文传播
java·spring boot·后端
计算机毕设定制辅导-无忧学长17 小时前
《基于Spring Boot的迷游哈游戏综合服务平台的开发》
java·vue.js·spring boot·mysql·迷游哈游戏综合服务平台
charliejohn17 小时前
计算机考研 408 数据结构 图论-关键路径
数据结构·图论
非优秀程序员1 天前
第05章 播放器大战,暴风、快播与那一夜|《互联网产品恩仇录》
算法
非优秀程序员1 天前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构