0
点赞
收藏
分享

微信扫一扫

【华为机试真题详解】数大雁【2022 Q2 | 100分】


文章目录

  • ​​前言​​
  • ​​详解试题​​
  • ​​1419. 数青蛙​​
  • ​​华为机试题. 数大雁​​
  • ​​题目解析​​
  • ​​数青蛙代码实现​​
  • ​​数大雁不考虑叫声不完整的情况​​
  • ​​数大雁考虑叫声不完整的情况​​

前言

《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。

如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议!

本文解法非最优解(即非性能最优)。

详解试题

平台

试题

LeetCode

​​1419. 数青蛙(中等)​​

华为机试

​​【华为机试真题 Python实现】数大雁【2022 Q2 100分】​​

1419. 数青蛙

给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 “croak” )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 “croak” 。

请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。

要想发出蛙鸣 “croak”,青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。如果字符串 croakOfFrogs 不是由若干有效的 “croak” 字符混合而成,请返回 -1 。

华为机试题. 数大雁

一群大雁往南飞,给定一个字符串记录地面上的游客听到的大雁叫声,请给出叫声最少由几只大雁发出。

具体的:

大雁发出的完整叫声为”quack“,因为有多只大雁同一时间嘎嘎作响,所以字符串中可能会混合多个”quack”。
大雁会依次完整发出”quack”,即字符串中’q’ ,‘u’, ‘a’, ‘c’, ‘k’ 这5个字母按顺序完整存在才能计数为一只大雁。如果不完整或者没有按顺序则不予计数。
如果字符串不是由’q’, ‘u’, ‘a’, ‘c’, ‘k’ 字符组合而成,或者没有找到一只大雁,请返回-1。

题目解析

我在LeetCode上有一道类似的题目,主要是对异常部分的描述有些不同,大家可以看下上面标黄的两句话。

在LeetCode测试发现只要字符串中的字符不能构成完整的叫声时,是不会计算有效字符串的个数的,直接输出​​-1​​就可了。

数大雁这道题里多了一句或者没有找到一只大雁 就很奇怪了,就是有一个正常的就需要统计呗,这个明显增加的题目的难度,已经不是一道​​100分​​​的题目了,因为没有在正式的机试环境下测试过,大家可以按​​数青蛙​​的解法先提交一次,如果不能完全通过再考虑复杂的情况。

下面我们就分别看下题目求解的思考过程,先以数青蛙为例:

我们用一个数组 states 来记录🐸叫个匹配状态

如果我们只是对字符计数的话,当遇到 ​​kaorc​​的情况就很难处理了,因为我们已知字符是顺序出现的,只有前一项的个数存在时后一项的字符才是有意义的,所有状态这里特殊处理一下,对后一项 +1 时 同时 对前一项 -1,这样当我们遇到字符 k 时 记录表中的数量和就是重复的🐸个数。

一只青蛙的计数:

【华为机试真题详解】数大雁【2022 Q2 | 100分】_Python


有叫声重叠的计数:

计数是我们 假定 当前重叠的字符再未遍历的地方都有字符与之生成完整的叫声。

【华为机试真题详解】数大雁【2022 Q2 | 100分】_算法_02

数青蛙代码实现

class Solution:
def minNumberOfFrogs(self, croakOfFrogs: str) -> int:
base = "croak"
states = [0] * len(base)
counts = 0
for c in croakOfFrogs:
if c == base[0]:
states[0] += 1
else:
index = base.index(c)
states[index-1] -= 1
states[index] += 1
if c == base[-1]:
states[-1] -= 1

# 如果再等于k时进行统计,需要在循环结束后再进行一次统计操作
# 最后一个字符时k的情况
counts = max(counts, sum(states))
# 出现-1时,说明无法构成croak,直接跳出
if -1 in states:
return -1
else:
if sum(states) != 0:
return -1
return

数大雁不考虑叫声不完整的情况

数大雁这道题,如果不考虑叫声不完整的情况只需要更换base = "quack"就可以了

while 1:
try:
chars = input()
base = "quack"
states = [0] * len(base)
counts = 0
for c in chars:
if c == base[0]:
states[0] += 1
else:
index = base.index(c)
states[index-1] -= 1
states[index] += 1
if c == base[-1]:
states[-1] -= 1

counts = max(counts, sum(states))
if -1 in states:
print(-1)
break
else:
if sum(states) != 0:
print(-1)
else:
print(counts)

数大雁考虑叫声不完整的情况

【华为机试真题详解】数大雁【2022 Q2 | 100分】_算法_02


我们还用上面的图解释下这个情况,因为我们再前面的编码中假设后面的字符会存在,并且在遍历到后面时,发现不存在完整的字符会直接跳出循环,打印-1。

我在统计第一部分时就可以直接计算 ​​sum(states)​​ 为🐸的个数,但在数大雁的题目中复杂考虑的场景是不能使用这个假设的。

我们需要在统计时,减掉不完整的字符串导致的 多算的大雁个数,也就时在统计到k字符时,最多再向后遍历 ​​sum(states)​​ -1 个k 来检查是否能构成完整的叫啥,不能构成的话需要减去对应的数量。

计算剩余字符串是否满足剩余的叫声

# 计算剩余字符串是否满足剩余的叫声
temp = [t for t in states]
temp[-1] = 0
max_ = sum(temp)
for j in range(i, len(chars)):
index = base.index(chars[j])
if temp[index - 1]:
temp[index - 1] -= 1
temp[index] += 1
if temp[-1] == max_:
break

数大雁完成代码实现

while 1:
try:
chars = input()
base = "quack"
states = [0] * len(base)
dp = []
for i in range(len(chars)):
index = base.index(chars[i])
if index == 0:
states[index] += 1
else:
if states[index - 1]:
states[index - 1] -= 1
states[index] += 1

if base[-1] == chars[i]:
if states[-1] != 0:
# 计算剩余字符串是否满足剩余的叫声
temp = [t for t in states]
temp[-1] = 0
max_ = sum(temp)
for j in range(i, len(chars)):
index = base.index(chars[j])
if temp[index - 1]:
temp[index - 1] -= 1
temp[index] += 1
if temp[-1] == max_:
break
dp.append(temp[-1] + 1)
states[-1] -= 1

print(max(dp) if dp else -1)
except Exception as e:
break


举报

相关推荐

0 条评论