LeetCode 1745. 回文串分割 IV(分为三个回文串,manacher)

2024-04-15 22:48

本文主要是介绍LeetCode 1745. 回文串分割 IV(分为三个回文串,manacher),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

给你一个字符串 s ,如果可以将它分割成三个 非空 回文子字符串,那么返回 true ,否则返回 false 。

当一个字符串正着读和反着读是一模一样的,就称其为 回文字符串 。

示例 1:

输入:s = “abcbdd”
输出:true
解释:“abcbdd” = “a” + “bcb” + “dd”,三个子字符串都是回文的。
示例 2:

输入:s = “bcbddxy”
输出:false
解释:s 没办法被分割成 3 个回文子字符串。

提示:

3 <= s.length <= 2000
s​​​​​​ 只包含小写英文字母。

思路:
最简单的是n^2 DP思路,维护 d p [ i ] [ j ] dp[i][j] dp[i][j]代表 [ i , j ] [i,j] [i,j]部分字符串是否回文,不再赘述。
通过马拉车算法可以做到O(n),依据的是下面这个结论,证明没有很看懂…(何逊大佬的题解)

在这里插入图片描述
由此,可以枚举回文前缀,再枚举后面部分的最长回文前缀和最长回文后缀,看是否存在合法情况。

class Solution {
public:void manacher(vector<int>& f, vector<int>& R, string& s) {int id = 0, mx = 0;int n = s.size();for(int i = 0;i < n;i++) {if(i < id + mx) {f[i] = min(id + mx - i, f[id * 2 - i]);}while(i - f[i] - 1 >= 0 && i + f[i] + 1 < n && s[i - f[i] - 1] == s[i + f[i] + 1]) f[i]++;if(id + mx < i + f[i]) {id = i;mx = f[i];}R[i - f[i]] = f[i];}for(int i = 1;i < n;i++) {R[i] = max(R[i - 1] - 1, R[i]);}}bool checkPartitioning(string s) {string str = "#";for(int i = 0;i < s.size();i++) {str += s[i];str += "#";}int n = str.size();vector<int>dp(n, 0);vector<int>R(n, 0);manacher(dp, R, str);vector<bool>pre(n, 0);int lst = 1;for(int i = 1;i < n;i++) {if(dp[i] == i) {//维护后半部分的最长回文后缀while(lst < n && (dp[lst] != n - 1 - lst || lst - dp[lst] - 1 <= i + dp[i])) {lst++;}if(lst >= n - 1) break;int l = i + dp[i] + 1, r = lst - dp[lst] - 1, pos = (l + r) >> 1;if(dp[pos] >= r - pos) {return true;}//维护后半部分的最长回文前缀int L = l + R[l] * 2 + 1, R = n - 1;pos = (L + R) >> 1;if(L < R && dp[pos] >= R - pos) {return true;}}}return false;}
};

这篇关于LeetCode 1745. 回文串分割 IV(分为三个回文串,manacher)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907143

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

csu1328(近似回文串)

题意:求近似回文串的最大长度,串长度为1000。 解题思路:以某点为中心,向左右两边扩展,注意奇偶分开讨论,暴力解即可。时间复杂度O(n^2); 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#inclu

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室