【华为OD】2024D卷——万能字符拼写

题目描述:
有一个字符串数组words和一个字符串chars。
假如可以用chars中的字母拼写出words中的某个“单词”(字符串),那么我们就认为你掌握了这个单词。
words的字符仅由a—z英文小写字母组成。例如:abc
chars由a-z英文小写字母和“?”组成。
其中英文问号”?”表示万能字符,能够在拼写时当做任意一个英文字母。例如:“?”可以当做"a"等字母。
注意:每次拼写时,chars中的每个字母和万能字符都只能使用一次。
输出词汇表words中你掌握的所有单词的个数。没有掌握任何单词,则输出0。

输入描述:
第1行输入数组words的个数,记为N。
从第2行开始到第N+1行依次输入数组words的每个字符串元素。
第N+2行输入字符串chars。

输出描述:
输出一个整数,表示词汇表words中你掌握的单词个数。

注意:
1 <= words length <=100
1 <= words[i].length, chars.length <= 100
所有字符串中都仅包含小写英文字母、英文问号
示例1
输入:
4
cat
bt
hat
tree
atach??
输出:
说明:3
可以拼写字符串“cat”、“bt”和"hat"

解题思路:

1、输入预处理:words按照字符列表存储,chars字符串转为set()

2、拼写验证

        ·遍历words中的每个word,确认每个word中的字符均可在chars_set()中找到

        ·统计每个word找不到的字符,若等于1且chars中存在'?',可以被拼写;否则不能被拼写

3、计数:验证可以拼写,count + 1


代码部分

def count_words_spellable(words, chars):
    chars_set = set(chars)
    question_mark = 1 if '?' in chars_set else 0
    count = 0
    for word in words:
        word_set = set(word)
        temp_count = 0      #临时统计在word中、不再chars中的字符个数
        for c in word_set:
            if c not in chars_set:
                temp_count += 1
        if temp_count == 0:     #word中字符均在chars中可以找到,则word可以被拼写
            count += 1
            continue
        else:       #word中字符存在chars中无法找到的情况
            if question_mark == temp_count:     #若仅1个字符找不到,且chars中存在"?",则word可以被拼写
                count += 1
                continue
    return count

按照上面set()的解法,虽然满足示例给出的输入输出。

但当chars中存在某个字母或者"?"重复时,且words中的word存在重复字母时,无法确认拼写时使用对应字母了几次。

其他思路:

由于题目中存在描述“注意:每次拼写时,chars中的每个字母和万能字符都只能使用一次。

可以理解为,假如chars = 'aaa',这里的chars[0]的a和chars[1]、chars[2]的a均可使用一次。

这样的话

1、可以使用hash表的方法,来存储chars中每个字母的个数,然后与word中字母的个数进行比较判断。

2、word中字母均能在chars中找到,且对应字母个数小于chars中对应字母,可拼写

3、word中字母存在无法在chars中找到的情况时,统计个数tmp_count,若tmp_count小于chars中'?'的个数,可拼写


代码部分

#方法②——字典(hash表)
def count_spellable_words(words, chars):
    # 统计chars中每个字母的出现次数,以及'?'的数量
    char_count = {'?': 0}
    for c in chars:
        if c in char_count:
            char_count[c] += 1
        else:
            char_count[c] = 1
    question_marks = char_count.pop('?') if '?' in char_count else 0
    # 遍历words数组,验证每个单词
    count = 0
    for word in words:
        # 临时字典,用于跟踪当前单词的字符需求
        temp_count = {'?': 0}
        spellable = True
        # 检查单词中的每个字符
        for c in word:
            if c in temp_count:
                temp_count[c] += 1
            elif c in char_count:
                temp_count[c] = 1
                if char_count[c] == 0:  # 如果该字符在chars中已用完
                    spellable = False
                    break
                char_count[c] -= 1
            else:
                # 如果字符不在chars中,且没有足够的'?'
                if question_marks == 0:
                    spellable = False
                    break
                temp_count['?'] += 1    #统计消耗chars中'?',方便后续恢复
                question_marks -= 1
        if spellable:
            count += 1
            # 恢复char_count和question_marks状态,以便下一个单词的验证
        for c in temp_count:
            if c in char_count:
                char_count[c] += temp_count[c]
        question_marks += temp_count.get('?', 0)
    return count

这样既满足题目输出,更换输入:

4
cat
bt
hat
tre
atach??

输出:

4

说明:'tre'中,'r'、'e'可以被两个'?'替换


知识点:字符串、列表、hash表


结语:越简单的题目解法应该越多,请路过大神留下新的思路供本小白学习一下,打开思路

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值