问题内容
给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 "croak" )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 “croak” 。请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。
注意:要想发出蛙鸣 "croak",青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。
如果字符串 croakOfFrogs 不是由若干有效的 "croak" 字符混合而成,请返回 -1 。
解法
由于本题限制croak字符不完整,就不会发出声音,所以得出
1. croak五个字符的数量是否一致
2. 并且croak五个字符的各个位置是否都是递增
不满足以上情况,结果为-1
因为结果输出是完成所有蛙鸣的最少数目的青蛙。
由此可以得出一个蛙鸣完成的区间是否有重叠,有重叠便是需要多个青蛙同时进行
时间复杂度
代码如下:
时间复杂度:O(n)
func minNumberOfFrogs(croakOfFrogs string) int {
croak := "croak"
croakMap := make(map[uint8]Str, 0)
strLen := len(croakOfFrogs)
for i:=0; i<5; i++ {
str := Str{ make([]int, 0), 0}
croakMap[croak[i]] = str
}
for j:=0; j<strLen; j++ {
str := croakMap[croakOfFrogs[j]]
str.cnt++
str.pos = append(str.pos, j)
croakMap[croakOfFrogs[j]] = str
}
for i:=1; i<5; i++ {
if croakMap[croak[i]].cnt != croakMap[croak[i-1]].cnt {
return -1
}
for j:=0; j<croakMap[croak[i-1]].cnt; j++ {
if croakMap[croak[i-1]].pos[j] > croakMap[croak[i]].pos[j] {
return -1
}
}
}
vis := make([]int, 100010)
cLen := len(croakMap[croak[0]].pos)
for i:=0; i<cLen; i++ {
vis[croakMap[croak[0]].pos[i]] = 1
vis[croakMap[croak[4]].pos[i]] = 2
}
res := 0
cnt := 0
for i:=0; i<strLen; i++ {
if vis[i] == 1 {
cnt++
} else if vis[i] == 2 {
cnt--
}
res = Max(res, cnt)
}
if cnt != 0 {
return -1
}
return res
}
func Min(i, j int) int {
if i > j {
return j
}
return i
}
func Max(i, j int) int {
if i > j {
return i
}
return j
}
type Str struct {
pos []int
cnt int
}