华为OD机试-- 数大雁 E100

阅读原文:https://www.xiaozaoshu.top/articles/goose-count

题目描述:

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

具体的

  • 大雁发出的完整叫声为”quack“,因为有多只大雁同一时间嘎嘎作响,所以字符串中可能会混合多个”quack”

  • 大雁会依次完整发出”quack”, 即字符串中q,u,a,c,k这5个字母按顺序完整存在才能计数为一只大雁如果不完整或者没有按顺序则不予计数。

  • 如果字符串不是由q,u,a,ck字符组合而成,或者没有找到一只大雁,请返回-1

输入描述

一个字符串,包含大雁quack的叫声。1<=字符串长度<=1000,字符串中的字符只有q,u,a,c,k

输出描述

大雁的数量

示例1

输入

quackquack

输出

1
这个输入字符串正好包含两个完整的、连续的 “quack”。一只大雁可以发出这样的声音序列,所以最少需要 1 只大雁。

示例2

输入

qaauucqckk

输出

-1

这个输入字符串中的字符虽然都是 ‘q’、‘u’、‘a’、‘c’、‘k’ 中的一个,但是它们的顺序不正确。没有一个完整的 “quack” 序列,因此返回 -1。

示例3

输入

quacqkuackquack

输出

2

这个输入字符串可以被解释为两只大雁的叫声交错:

  • 第一只大雁:quack
  • 第二只大雁:quackquack
  • 第二只大雁发出了两次完整的 “quack”,而第一只大雁只发出了一次。

因此,最少需要 2 只大雁才能产生这样的叫声序列。

输入

qququaauqccauqkkcauqqkcauuqkcaaukccakkck

输出

5

这个输入字符串可以被解释为五只大雁的叫声交错。每只大雁至少完整发出了一次 “quack”。

解题思路

题目要求最少的数量

假设每只大雁叫完 quack 以后,还会接着叫,这样可以使得大雁数量最少

如果出现 q,但是没有大雁等待发出 q 这个音节,说明需要有一只新的大雁的叫声

使用一个 List 来记录每只大雁当等待发出的音节。遍历输入字符串,对每个字符进行处理:

  • 检查是否有某只大雁正在等待发出当前音节,如果没有,且当前是 q 这个音节,这个就增加一只新的大雁来发出这个音节,否则视为异常
  • 如果找到了匹配的大雁,更新这只大雁等待发出的音节。

源码

package com.redjujubetree.huawei;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class AMain {

	private static List<Goose> list = new ArrayList<>();
	public static void main(String[] args) {
		try{
			Scanner scanner = new Scanner(System.in);
			String quacks = scanner.nextLine();
			for (int i = 0; i < quacks.length(); i++) {
				// 当前需要发生的音节
				char sound = quacks.charAt(i);
				// 下一个需要发出的音节
				Character nextSound = nextSound(sound);
				int i1 = hasWait(sound);
				if (i1 == -1) {
					// 需要增加大雁数量的情况
					if ('q' == sound) {
						list.add(new Goose('u'));
					} else {
						throw new IllegalArgumentException("-1");
					}
				} else {
					// 更新下一个需要发出的音节
					list.get(i1).sound = nextSound;
					// 如果当前音节是k,则表示该大雁已经发出了所有音节
					if ('k' == sound) {
						list.get(i1).complated = true;
					}
				}
			}
			System.out.println(list.stream().filter(goose -> goose.complated).count());
		} catch (Exception e) {
			System.out.println(-1);
		}

	}

	// 等待发出该音节的大雁
	private static int hasWait(char c) {
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).sound == c) {
				return i;
			}
		}
		return -1;
	}

	// 发出当前音节后,下一个可以发出的音节
	public static Character nextSound(char ch) {
		switch (ch) {
			case 'q':
				return 'u';
			case 'u':
				return 'a';
			case 'a':
				return 'c';
			case 'c':
				return 'k';
			case 'k':
				return 'q';
		}
		throw new IllegalArgumentException("-1");
	}
	private static class Goose {
		public char sound;
		public Boolean complated = false;
		public Goose(char sound) {
			this.sound = sound;
		}
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚定的小辣鸡在努力

你的支持是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值