2022-07-21:给定一个字符串str,和一个正数k,
你可以随意的划分str成多个子串,
目的是找到在某一种划分方案中,有尽可能多的回文子串,长度>=k,并且没有重合。
返回有几个回文子串。
来自optiver。

答案2022-07-21:

马拉车算法+贪心。

代码用rust编写。代码如下:

use rand::Rng;
fn main() {
let n: i32 = 20;
let r = 3;
let test_time: i32 = 50000;
println!("测试开始");
for i in 0..test_time {
let str = random_string(n, r);
let k = rand::thread_rng().gen_range(0, str.len() as i32) + 1;
let ans1 = max1(&str, k);
let ans2 = max2(&str, k);
if ans1 != ans2 {
println!("i = {}", i);
println!("str = {}", str);
println!("k = {}", k);
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
println!("出错了!");
break;
}
}
println!("测试结束");
}
// 暴力尝试
// 为了测试
// 可以改成动态规划,但不是最优解
fn max1(s: &str, k: i32) -> i32 {
if s.len() == 0 {
return 0;
}
let mut str = s.as_bytes().to_vec();
return process1(&mut str, 0, k);
} fn process1(str: &mut Vec<u8>, index: i32, k: i32) -> i32 {
if str.len() as i32 - index < k {
return 0;
}
let mut ans = process1(str, index + 1, k);
for i in index + k - 1..str.len() as i32 {
if is_palindrome(str, index, i) {
ans = get_max(ans, 1 + process1(str, i + 1, k));
}
}
return ans;
} fn is_palindrome(str: &mut Vec<u8>, mut ll: i32, mut rr: i32) -> bool {
while ll < rr {
if str[ll as usize] != str[rr as usize] {
return false;
}
ll += 1;
rr -= 1;
}
return true;
} fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
} fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
} // 最优解
// 时间复杂度O(N)
fn max2(s: &str, k: i32) -> i32 {
if s.len() == 0 {
return 0;
}
let mut str = manacher_string(s);
let mut p = vec![];
for _ in 0..str.len() as i32 {
p.push(0);
}
let mut ans = 0;
let mut next = 0;
// k == 5 回文串长度要 >= 5
// next == 0
// 0.... 8 第一块!
// next -> 9
// 9.....17 第二块!
// next -> 18
// 18....23 第三块
// next一直到最后!
next = manacher_find(&mut str, &mut p, next, k);
while next != -1 {
next = if str[next as usize] == ('#' as u8) {
next
} else {
next + 1
};
ans += 1;
next = manacher_find(&mut str, &mut p, next, k);
}
return ans;
} fn manacher_string(s: &str) -> Vec<u8> {
let str = s.as_bytes().to_vec();
let mut ans: Vec<u8> = vec![];
for _ in 0..str.len() as i32 * 2 + 1 {
ans.push(0);
}
let mut index: i32 = 0;
for i in 0..ans.len() as i32 {
if (i & 1) == 0 {
ans[i as usize] = '#' as u8;
} else {
ans[i as usize] = str[index as usize];
index += 1;
}
}
return ans;
} // s[l...]字符串只在这个范围上,且s[l]一定是'#'
// 从下标l开始,之前都不算,一旦有某个中心回文半径>k,马上返回右边界
fn manacher_find(s: &mut Vec<u8>, p: &mut Vec<i32>, l: i32, k: i32) -> i32 {
let mut c = l - 1;
let mut r = l - 1;
let n = s.len() as i32;
for i in l..s.len() as i32 {
p[i as usize] = if r > i {
get_min(p[(2 * c - i) as usize], r - i)
} else {
1
};
while i + p[i as usize] < n
&& i - p[i as usize] > l - 1
&& s[(i + p[i as usize]) as usize] == s[(i - p[i as usize]) as usize]
{
p[i as usize] += 1;
if p[i as usize] > k {
return i + k;
}
}
if i + p[i as usize] > r {
r = i + p[i as usize];
c = i;
}
}
return -1;
} // 为了测试
fn random_string(n: i32, r: i32) -> String {
let mut ans: String = String::from("");
let ans_len = rand::thread_rng().gen_range(1, n);
for _ in 0..ans_len {
ans.push((rand::thread_rng().gen_range(0, r) + 'a' as i32) as u8 as char);
}
return ans;
}

执行结果如下:


左神java代码

2022-07-21:给定一个字符串str,和一个正数k, 你可以随意的划分str成多个子串, 目的是找到在某一种划分方案中,有尽可能多的回文子串,长度>=k,并且没有重合。 返回有几个回文子串。 来的更多相关文章

  1. poj1056(字符串判断是否存在一个字符串是另一个字符串的前缀)

    题目链接:https://vjudge.net/problem/POJ-1056 题意:给定一个字符串集,判断是否存在一个字符串是另一个字符串的前缀. 思路:和hdoj1671一样,有两种情况: 当前 ...

  2. Java-map-第一题 (Map)利用Map,完成下面的功能: 从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该 年没有举办世界杯,则输出:没有举办世界杯。 附:世界杯冠军以及对应的夺冠年份,请参考本章附录。 附录

    第一题 (Map)利用Map,完成下面的功能: 从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队.如果该 年没有举办世界杯,则输出:没有举办世界杯. 附:世界杯冠军以及对应的夺冠年 ...

  3. Go hashcode 输入一个字符串,得到一个唯一标识码

    如何输入一个字符串,得到一个唯一的hashcode? 例子如下: package main import ( "fmt" "hash/crc32" ) // S ...

  4. JS判断一个字符串是否包含一个子串函数.

    微信小程序 JS判断一个字符串是否包含一个子串函数. //str 字符串,name子串     contains:function(str,name){         if(str.indexOf( ...

  5. Js判断一个字符串是否包含一个子串

    Js中经常遇到判断一个字符串是否包含一个子串,java语言中有containes的方法,直接调用就可以了.除非引用第三方数据库,Js中没有contains方法. 为了实现更java语言中contain ...

  6. MSSQL sqlserver 统计"一个字符串"在"另一个字符串"中出现的次数的方法

    转自 http://www.maomao365.com/?p=9858  摘要: 下文讲述sqlserver中最快获取一个字符串在另一个字符串中出现个数的方法分享 实验环境:sql server 20 ...

  7. python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False。

    python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False. 重难点:定义函数的方法.使用str类型的find()函数,可以 ...

  8. oracle中一个字符串包含另一个字符串中的所有字符

    oracle中一个字符串包含另一个字符串中的所有字符 --解决监理报告中所勾选的标段信息,与该用户所管理的标段字符串不匹配的问题. select * from a where instr(a,b)&g ...

  9. Java 一个字符串在另外一个字符串出现次数

    统计一个字符串在另外一个字符串出现次数 代码如下: package me.chunsheng.javatest; import java.util.regex.Matcher; import java ...

  10. js中如何判断一个字符串包含另外一个字符串?

    js中判断一个字符串包含另外一个字符串的方式比较多? 比如indexOf()方法,注意O是大写. var test="this is a test"; if(test.indexO ...

随机推荐

  1. Android日常--今日的APP进度+1

    学了这么久的APP,是时候拿出来实践一下啦! 今天洗的内容都比较基础,基本上不涉及到后台代码的编写,看到本阶段的目标需要连接数据库,也是有被震住哈哈哈哈哈: 我发现,第一阶段主要分为两个界面,第一个注 ...

  2. 声网发布教育新品:灵动课堂全球覆盖学生超400万,互动白板首创H5课件

    3月31日,全球实时互动云服务商声网Agora在北京举行教育产品发布会,正式发布教育行业首款aPaaS产品"灵动课堂",和首个支持H5课件的白板PaaS产品"互动白板&q ...

  3. Java多线程——Thread类

    Java多线程--Thread类 Java 中线程实现方式有两种: 继承Thread类,并重写run方法 实现Runnable接口的run方法 Thread类 使用方法:继承Thread类,并重写ru ...

  4. Windows下解决python pip命令下载慢的方法(超简单)

    首先,常用的国内镜像: 1 https://pypi.tuna.tsinghua.edu.cn/simple/ 清华大学(推荐) 2 http://pypi.douban.com/simple/ 豆瓣 ...

  5. 使用Docusaurus搭建个人网站

    第一次使用 Docusaurus 搭建我的个人网站 第一步 安装 node 环境 安装 Node.js 16.14 或更高版本(可以通过执行 node -v 命令来查看当前所用的 Node.js 版本 ...

  6. 原型继承和 Class 继承

    涉及面试题: 原型如何实现继承? Class 如何实现继承? Class 本质是什么? ⾸先先来讲下 class ,其实在 JS 中并不存在类, class 只是语法糖,本质还是函数. class P ...

  7. 探究平台化设计的核心思想和Lattice的设计原则

    一. 平台对业务敏捷支撑的挑战 早期阿里的交易中台遇到了一些挑战,这个在毗卢的博客中有提到,主要遇到了这些问题:新小业务都有一个成长规律,在早期业务模式验证阶段,需要的玩法比较简单,希望能频繁的发布快 ...

  8. Vue 路由导航守卫

    Vue 路由导航守卫 一:全局守卫 (1) router.beforeEach beforeEach((to, from, next) => {}) 接收三个参数,在路由切换成功之前调用 to ...

  9. Unity3D中的Attribute详解(六)

    本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...

  10. keepalived的简单使用

    原理简述 本篇主要学习keepalived配合nginx实现nginx的高可用, 也就是需要keepalived检测到nginx宕机时停用keepalived, 备用keepalived会自动接收过来 ...