2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果。
2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果。
福大大 答案2021-04-03:
1.暴力法。
2.DC3算法。自然智慧想不到,需要练敏感度。
2.1.构造字符串。str = str1+最小字符+str2。
2.2.对str进行dc3算法,求出rank数组。
2.3.遍历0到str1长度,找到小于str2起始位置的序号。
2.4.根据序号算出bestSplit值。时间紧,先放一放。
2.5.根据bestSplit拆分str1,然后合并。返回str1左+str2+str1右。
代码用golang编写。代码如下:
package main
import (
"fmt"
"index/suffixarray"
"math/rand"
"time"
"unsafe"
)
func main() {
rand.Seed(time.Now().Unix())
//YJWBRFKBMYQWFCRTSA
//YTOFNTX
cnt := 0
const TOTAL = 10000
for i := 0; i < TOTAL; i++ {
s1 := newRandString()
s2 := newRandString()
fmt.Println("s1 = ", s1)
fmt.Println("s2 = ", s2)
ret1 := right(s1, s2)
ret2 := maxCombine(s1, s2)
fmt.Println("暴力的答案:", ret1)
fmt.Println("DC3的答案:", ret2)
if ret1 == ret2 {
fmt.Println("正确")
cnt++
} else {
fmt.Println("错误")
}
fmt.Println("-------------")
}
fmt.Println("总数:", TOTAL)
fmt.Println("正确:", cnt)
}
func newRandString() string {
retLen := rand.Intn(20) + 5
ret := make([]byte, retLen)
for i := 0; i < retLen; i++ {
ret[i] = byte(rand.Intn(26) + 'A')
}
return string(ret)
}
func right(s1 string, s2 string) string {
if len(s1) == 0 {
return s2
}
if len(s2) == 0 {
return s1
}
ans := s1 + s2
temp := ""
best := len(s1)
for i := 0; i < len(s1); i++ {
temp = s1[0:i] + s2 + s1[i:]
if temp > ans {
ans = temp
best = i
}
}
fmt.Println("暴力best = ", best)
return ans
}
// 正式方法 O(N+M) + O(M^2)
// N : s1长度
// M : s2长度
func maxCombine(s1 string, s2 string) string {
if len(s1) == 0 {
return s2
}
if len(s2) == 0 {
return s1
}
str1 := []byte(s1)
str2 := []byte(s2)
N := len(str1)
M := len(str2)
min := str1[0]
max := str1[0]
for i := 1; i < N; i++ {
min = getMin(min, str1[i])
max = getMax(max, str1[i])
}
for i := 0; i < M; i++ {
min = getMin(min, str2[i])
max = getMax(max, str2[i])
}
all := make([]byte, N+M+1)
index := 0
for i := 0; i < N; i++ {
all[index] = str1[i] - min + 2
index++
}
all[index] = 1
index++
for i := 0; i < M; i++ {
all[index] = str2[i] - min + 2
index++
}
dc3 := NewFddSa(all)
comp := N + 1
for i := 0; i < N; i++ {
if dc3.Rank[i] < dc3.Rank[comp] {
best := bestSplit(s1, s2, i)
//best := i //这句代码是错的
fmt.Println("DC3的best = ", best)
return s1[0:best] + s2 + s1[best:]
}
}
return s1 + s2
}
func bestSplit(s1 string, s2 string, first int) int {
N := len(s1)
M := len(s2)
end := N
for i, j := first, 0; i < N && j < M; i, j = i+1, j+1 {
if s1[i] < s2[j] {
end = i
break
}
}
bestPrefix := s2
bestSplit := first
for i, j := first+1, M-1; i <= end; i, j = i+1, j-1 {
curPrefix := s1[first:i] + s2[0:j]
if curPrefix >= bestPrefix {
bestPrefix = curPrefix
bestSplit = i
}
}
if bestSplit != first {
fmt.Println("注意,first = ", first, " ,bestSplit = ", bestSplit)
}
return bestSplit
}
func getMax(a byte, b byte) byte {
if a > b {
return a
} else {
return b
}
}
func getMin(a byte, b byte) byte {
if a < b {
return a
} else {
return b
}
}
type FddSa struct {
Sa []int
Rank []int
}
func NewFddSa(bytes []byte) *FddSa {
ret := &FddSa{}
ret.Rank = make([]int, len(bytes))
ret.Sa = make([]int, len(bytes))
index := suffixarray.New(bytes)
p1 := uintptr(unsafe.Pointer(index)) //获取指针
p1 += 24
p2 := *(*[]int32)(unsafe.Pointer(p1)) //将指针转行成切片
for i := 0; i < len(bytes); i++ {
ret.Sa[i] = int(p2[i]) //sa数组
ret.Rank[int(p2[i])] = i //rank数组
}
return ret
}
执行结果如下:

2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果。的更多相关文章
- 给定两个字符串 s 和 t,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。
给定两个字符串 s 和 t,它们只包含小写字母.字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母.请找出在 t 中被添加的字母. 示例: 输入: s = "abcd" ...
- 给定两个字符串,均只包含英文字母,需区分大小写,一个是源字符串SS(长度<1000), 另一个是目标字符串TS(长度<1000),请问能否通过删除SS中的字符(不改变顺序)将它变换成TS,如果可以输出“YES",不可以则输出“NO"。 输入说明:第一行为源字符串SS,第二行为目标字符串TS。
import java.util.Scanner;/* 给定两个字符串,均只包含英文字母,需区分大小写,一个是源字符串SS(长度<1000), 另一个是目标字符串TS(长度<1 ...
- 2021.04.03【NOIP提高B组】模拟 总结
T1 题目大意:求最小的 \(n\in[0,lim]\) 使得区间 \([L,R]\) 在线段树建树 \(build(0,n)\) 的区间内 考场时想到了正解,结果推式子退错了... 其实就是从下往上 ...
- poj 2774 后缀数组 两个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 31904 Accepted: 12 ...
- ✡ leetcode 161. One Edit Distance 判断两个字符串是否是一步变换 --------- java
Given two strings S and T, determine if they are both one edit distance apart. 给定两个字符串,判断他们是否是一步变换得到 ...
- [Swift]LeetCode712. 两个字符串的最小ASCII删除和 | Minimum ASCII Delete Sum for Two Strings
Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal. ...
- 【leet-code】712. 两个字符串的最小ASCII删除和
题目描述 给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 = "eat" ...
- poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11469 Accepted: 379 ...
- Q712 两个字符串的最小ASCII删除和
给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 = "eat" 输出: ...
- Python-求解两个字符串的最长公共子序列
一.问题描述 给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence).比如字符串1:BDCABA:字符串2:ABCBDAB.则这两个字符串的最长公共子序列长 ...
随机推荐
- psq强制携带-h
背景: pg更新后psql 指令必须携带 -h指令,导致很多直接使用"psql"的shell脚本无法连接. 方案: 1.挨个更新调用psql的地方: 显然太多了,改不过来. 2.新 ...
- Repeater 绑定数据是根据数据修改行的颜色值信息
<ItemTemplate> <tr <%# Eval("dayu20").ToString()=="0"? "style=' ...
- 12-如何使用Genarator逆向工程
使用逆向工程,帮我们更快的建立pojo类.mapper接口及xml映射文件等,无需手写,替代了一部分的mybatis功能. 一.导入MyGenarator逆向工程项目 二.修改xml配置文件 三.执行 ...
- AI 脸部美容,一键让你变瘦变美变老变年轻
目录 项目效果 项目安装 安装环境 项目使用 项目效果 随着 AI 技术的发展,你不仅随时可以看到自己的老了之后的样子,还能看到自己童年的样子 随着这部分技术的开源,会有越来越多的应用,当然我觉得前景 ...
- Android笔记--常用布局
线性布局--LinearLayout 线性布局的方向 orientation属性值:若为horizontal,内部视图在水平方向从左往右排列 若为vertical,内部视图在垂直方向从上往下排列 如果 ...
- 重构:banner 中 logo 聚合分散动画
1. 效果展示 在线查看 2. 开始前说明 效果实现参考源码:Logo 聚集与散开 原效果代码基于 react jsx 类组件实现.依赖旧,代码冗余. 我将基于此进行重构,重构目标: 基于最新依赖包, ...
- ElasticSearch可视化工具ElasticHD安装
ElasticHD两种安装方式 1.ElasticHD介绍 ElasticHD 支持 ES监控.实时搜索,Index template快捷替换修改,索引列表信息查看, SQL converts to ...
- 从零开始学Java系列之Java是什么?它到底是个啥?
全文大约[5000]字,不说废话,只讲可以让你学到技术.明白原理的纯干货!文章带有丰富案例及配图,只为让你更好的理解和运用文中的技术概念,给你带来具有足够的思想启迪...... ----------- ...
- .Net 6.0定义全局当前身份缓存对象
背景: 当前身份缓存对象顾名思义就是:当前登录的用户身份对象,那它解决了什么问题呢?其实在我们日常开发过程中经常能用的到几乎是必备的,就比如我给某个表插入数据时需要创建人或者一些权限的访问,都得用到当 ...
- 常用Linux系统命令、vim编辑命令汇总(看一遍用时候来查)
基本操作 pwd命令 作用:显示当前工作目录 用法:pwd cd命令 作用:改变目录位置 用法:cd [option] [dir] cd 目录路径 -进入指定目录 cd .. -返回父目录 cd / ...