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. 火狐浏览器调试eval源码

    火狐浏览器调试eval源码 firefox浏览器在网页调试上,有一个没法和chrome一比高下的功能,就是eval脚本的调试,有时前端架构使用了基于eval的方式,有时候可能是自己一个多行函数,每每遇 ...

  2. 《MySQL是怎样运行的》第三章小结

  3. AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...

  4. Android笔记-跳转到相册选择图片

    跳转到相册选择图片 即设置一个点击事件,点击之后即可跳转到相册进行图片的选择 具体的实现步骤: 界面很简单的啦,这里就直接将源代码放出来啦: <?xml version="1.0&qu ...

  5. Android笔记--查询联系人

    查询联系人 先在raw_contacts表里面查到每个联系人的不同的id,然后再根据各个id去查询各个联系人的详细信息 然后利用id得到相应的uri的值: 之后,就直接根据uri查询各个联系人的详细信 ...

  6. day02-容器功能

    容器功能 1.Spring注入组件的注解 Spring中的传统注解@Component.@Controller.@Service.@Repository,在SpringBoot中仍然有效. 2.@Co ...

  7. Fiddler一些用法学习记录

    最近项目中用Fiddler较多,只会之前掌握的一些最简单的用法显得有点不太够.记录一下学习到的新用法. 一.需要mock.打开AutoResponder,Add Rule,填上需要mock的网址,需要 ...

  8. 在echaerts中渲染50万条数据的优化方案

    背景:项目需求中要在页面上渲染大约50万条左右的波形数据图表 那么如何解决渲染中的卡顿呢? 肯定是要从服务端和前端一起优化这是毋庸置疑的. 1.服务端: 服务端耗时最多的一定是在数据库的筛选数据的行为 ...

  9. CF1801B题解

    CF1801B题解 传送门 更好的阅读体验 简化题意:有 n 个商店,每个商店卖 a,b 两种商品,价格分别为 \(a_i,b_i\),你需要在每个商店买一个商品,并且不能在所有商店都买同一种商品,最 ...

  10. python调用打印机打印文件,图片,pdf等

    引言 python连接打印机进行打印,可能根据需求的不同,使用不同的函数模块. 如果你只是简单的想打印文档,比如office文档,你可以使用ShellExecute方法,对于微软office的文档.p ...