2287. 重排字符形成目标字符串
题目链接:https://leetcode.cn/problems/rearrange-characters-to-make-target-string
难度:简单
1.题目
给你两个下标从 0 开始的字符串 s 和 target 。你可以从 s 取出一些字符并将其重排,得到若干新的字符串。
从 s 中取出字符并重新排列,返回可以形成target的最大副本数。
2.示例
输入:s = "ilovecodingonleetcode", target = "code"
输出:2
输入:s = "abcba", target = "abc"
输出:1
输入:s = "abbaccaddaeea", target = "aaaaa"
输出:1
3.思路
一开始被示例1和2误导,以为是求s的连续字串是否有能构成target的副本数。由示例3可知题目要求为求在s中有的所有字符集合能构成多少个形如target的副本数。由此可以得以下思路:
- 将两个字符串分别转换成map集合,形式为map[字符元素]字符个数,s和target分别对应m1、m2
- 不断循环遍历m2集合,当每次集合m2中元素存在于m1中,且value值有m1大于m2时,m1对应value减去相应个数,每一次循环遍历m2集合后,副本数加一;否则退出遍历,返回统计得副本数
4.代码
func rearrangeCharacters(s string, target string) int {
count := 0 //最大副本数
m1 := map[string]int{}
for _, v := range s {//将s转出map集合
if _, ok := m1[string(v)]; ok {
m1[string(v)] += 1
} else {
m1[string(v)] = 1
}
}
m2 := map[string]int{}
for _, v := range target {//将target转出map集合
if _, ok := m2[string(v)]; ok {
m2[string(v)] += 1
} else {
m2[string(v)] = 1
}
}
i := 1
for i == 1 {//不断循环遍历m2集合
f := true//标志每次遍历m2集合是否有足够元素构成一个副本
for k, v := range m2 {//遍历m2集合
if v > m1[k] {//当出现m1集合已无法再拿出满足m1集合组成所需个数时,退出循环
i = 0
f = false
} else {
m1[k] -= v
}
}
if f {//当有足够得元素构成副本数时,计数加一
count++
}
}
return count
}
5.复杂度分析
设字符串s和target长度分别为
n
1
n_1
n1,
n
2
n_2
n2
时间复杂度:O(
m
a
x
(
n
1
,
n
2
)
max(n_1,n_2)
max(n1,n2))
空间复杂度:O(
m
a
x
(
n
1
,
n
2
)
max(n_1,n_2)
max(n1,n2))
6.改进
字符串s在转成map集合时可以只包含target中已有元素种类而不保存多余种类,从而使空间复杂度变成:O( m m m),其中m为target中所有的元素种类。