Go_2287. 重排字符形成目标字符串

该问题是一个关于字符串处理的算法题,要求找到从给定字符串s中最多能构建多少个目标字符串target的副本。关键在于比较两个字符串中字符的分布,然后进行模拟操作。首先将两个字符串转换为字符计数的映射,之后遍历目标字符串的映射,检查源字符串的映射是否足够提供所需的字符。若可以,则计数增加,否则结束遍历。最后返回计数值作为结果。
摘要由CSDN通过智能技术生成

2287. 重排字符形成目标字符串

题目链接:https://leetcode.cn/problems/rearrange-characters-to-make-target-string
难度:简单

1.题目

给你两个下标从 0 开始的字符串 starget 。你可以从 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的副本数。由此可以得以下思路:

  1. 将两个字符串分别转换成map集合,形式为map[字符元素]字符个数,starget分别对应m1m2
  2. 不断循环遍历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.复杂度分析

设字符串starget长度分别为 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中所有的元素种类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值