1170. 比较字符串最小字母出现频次

题目:

定义一个函数 f(s),统计 s 中(按字典序比较)最小字母的出现频次 ,其中 s 是一个非空字符串。

例如,若 s = “dcce”,那么 f(s) = 2,因为字典序最小字母是 “c”,它出现了 2 次。

现在,给你两个字符串数组待查表 queries 和词汇表 words 。对于每次查询 queries[i] ,需统计 words 中满足 f(queries[i]) < f(W) 的 词的数目 ,W 表示词汇表 words 中的每个词。

请你返回一个整数数组 answer 作为答案,其中每个 answer[i] 是第 i 次查询的结果。

示例 1:

输入:queries = [“cbd”], words = [“zaaaz”]
输出:[1]
解释:查询 f(“cbd”) = 1,而 f(“zaaaz”) = 3 所以 f(“cbd”) < f(“zaaaz”)。
示例 2:

输入:queries = [“bbb”,“cc”], words = [“a”,“aa”,“aaa”,“aaaa”]
输出:[1,2]
解释:第一个查询 f(“bbb”) < f(“aaaa”),第二个查询 f(“aaa”) 和 f(“aaaa”) 都 > f(“cc”)。

提示:

1 <= queries.length <= 2000
1 <= words.length <= 2000
1 <= queries[i].length, words[i].length <= 10
queries[i][j]、words[i][j] 都由小写英文字母组成

思路:

  1. 根据定义 f(s)=s.count(min(s)) 就可以快速计算最小字母出现的频次
  2. 将字母抽象为数字问题,将queries和words中的最小字母出现频次储存到q和w列表中
  3. 将w排序
  4. 遍历q中元素,二分法来选择比q中元素大的个数

语法知识:

min()函数可以计算字符串中的最小元素
len(w)-l是返回比目标元素大的个数
法:

bisect_right 的返回值表示在保持排序的情况下,插入 x 后它应该在哪个位置。这意味着,如果返回值为 i,那么 x 应该插入到 a[i] 之前。

注意:

bisect_right 会在列表中查找第一个大于等于 x 的元素,如果 x 已经存在于列表中,则返回值为 x 在列表中的下标加 1。
如果 x 比列表中所有元素都大,则返回值为列表的长度。
示例:

a = [1, 3, 5, 7, 9]
bisect_right(a, 4)
2
bisect_right(a, 10)
5
bisect_right(a, 3)
2

代码:

我的代码:

class Solution(object):
    def numSmallerByFrequency(self, queries, words):
        q = []
        w = []
        answer = []
        for s in words:
            w.append(s.count(min(s)))
        for n in queries:
            q.append(n.count(min(n)))
        w.sort()
        for i in q:
            l = 0
            r = len(w) - 1
            while l <= r:
                mid = (l + r) // 2
                if w[mid] <= i:
                    l = mid + 1  # 赋值给 l
                else:
                    r = mid - 1
            answer.append(len(w) - l)  # 添加到 answer 列表中
        return answer

灵神的代码简洁优雅:

class Solution:
    def numSmallerByFrequency(self, queries: List[str], words: List[str]) -> List[int]:
        a = sorted(s.count(min(s)) for s in words)
        return [len(a) - bisect_right(a, q.count(min(q))) for q in queries]

一些解释:

  1. 计算 words 中每个字符串的最小字母出现频次: a = sorted(s.count(min(s)) for s in words)
    for s in words: 循环遍历 words 列表中的每个字符串 s。
    min(s): 获取字符串 s 中的最小字母。
    s.count(min(s)): 计算最小字母在字符串 s 中出现的次数。
    sorted(…): 对所有字符串的最小字母出现频次进行排序,并存储到列表 a 中。

  2. 循环遍历查询字符串:

    return [len(a) - bisect_right(a, q.count(min(q))) for q in queries]
    for q in queries:
    循环遍历 queries 列表中的每个查询字符串 q。
    q.count(min(q)):
    计算查询字符串 q 中最小字母的出现频次。 bisect_right(a, q.count(min(q))):
    使用bisect_right 函数在排序后的列表 a 中找到第一个大于等于 q.count(min(q)) 的元素的下标,即 a 中所有小于
    q.count(min(q)) 的元素数量。

    len(a) - bisect_right(…):
    计算 a 中所有大于q.count(min(q)) 的元素数量,即 words 中最小字母出现频次大于 q 中最小字母出现频次的字符串数量。 […]:
    将每个查询字符串的比较结果存储到列表中,并返

回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值