简单题(5,7,8) | 豆包MarsCode AI刷题

70 阅读11分钟

第5题 寻找最大葫芦

问题描述

在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 aa 和另外两张相同牌面值的牌 bb。如果两个人同时拥有“葫芦”,我们会优先比较牌 aa 的大小,若牌 aa 相同则再比较牌 bb 的大小。

在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 maxmax。牌面值的大小规则为:A > K > Q > J > 10 > 9 > ... > 2,其中 A 的牌面值为1,K 为13,依此类推。

给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的“葫芦”,则输出 “0, 0”。


测试样例

样例1:

输入:n = 9, max = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1]
输出:[8, 5]

样例2:

输入:n = 9, max = 37, array = [9, 9, 9, 9, 6, 6, 6, 6, 13]
输出:[6, 9]

样例3:

输入:n = 9, max = 40, array = [1, 11, 13, 12, 7, 8, 11, 5, 6]
输出:[0, 0]

问题分析

这个问题是一个典型的组合优化问题,我们需要从给定的一组牌中找到符合“葫芦”规则的最大组合,并且这个组合的牌面值之和不超过给定的最大值。下面是对这个问题的逐步分析:

  1. 理解“葫芦”牌型:在德州扑克中,“葫芦”由三张相同牌面值的牌和另外两张相同牌面值的牌组成。如果两个人都有“葫芦”,我们首先比较三张牌的牌面值,如果相同,再比较两张牌的牌面值。

  2. 牌面值的表示:牌面值按照 A > K > Q > J > 10 > 9 > ... > 2 的顺序排列,其中 A 的牌面值为 1,K 的牌面值为 13,以此类推。

  3. 问题限制:组成“葫芦”的五张牌的牌面值之和不能超过给定的最大值 max

  4. 寻找最大“葫芦”:我们需要找到最大的“葫芦”组合,这意味着我们需要最大化三张相同牌的牌面值和两张相同牌的牌面值。

  5. 算法步骤

    • 统计牌面值:首先,我们需要统计每种牌面值的数量。
    • 检查可能的组合:然后,我们需要检查所有可能的“葫芦”组合,确保它们的牌面值之和不超过 max
    • 比较组合:对于每个有效的“葫芦”组合,我们需要比较它们的牌面值,找到最大的组合。
    • 输出结果:如果找到了有效的“葫芦”组合,输出三张相同牌的牌面值和两张相同牌的牌面值。如果没有找到,输出 "0, 0"。
  6. 实现细节

    • 使用一个数组或哈希表来统计每种牌面值的数量。
    • 遍历所有可能的三张牌的组合,并检查是否有两张牌的组合可以与它们配对形成“葫芦”。
    • 对于每个有效的组合,计算牌面值之和,并与当前找到的最大组合进行比较。
    • 跟踪并更新最大“葫芦”组合。
  7. 复杂度考虑:这个问题的时间复杂度主要取决于检查所有可能的“葫芦”组合的数量。由于我们需要检查所有三张牌的组合和两张牌的组合,时间复杂度可能相当高。然而,由于问题规模相对较小(最多9张牌),暴力搜索可能是可行的。

  8. 测试样例分析

    • 样例1:给定的牌可以形成多个“葫芦”,最大的是 [8, 5],因为 8+8+8+5+5=34,不超过最大值 34。
    • 样例2:最大的“葫芦”是 [6, 9],因为 6+6+6+9+9=36,不超过最大值 37。
    • 样例3:没有“葫芦”的牌面值之和不超过 40,所以输出 "0, 0"。

这个问题的解决方案需要仔细的实现和测试,以确保找到最大的有效“葫芦”组合。

解题代码

def solution(n, max, array):
    # Edit your code here
    array.sort(reverse = True)
    num_one = array.count(1)
    while 1 in array:
        array.remove(1)
    for i in range(num_one):
        array.insert(0, 1)
    num = {}
    for i in array:
        num[i] = num.get(i, 0) + 1
    re = [0, 0]
    print(num)
    
    for k in num:
        f = False
        if num.get(k) >= 3:
            re[0] = k
            for kk in  num:
                if kk != k and num.get(kk) >= 2:
                    re[1] = kk
                    if 3 * re[0] + 2 * re[1] <= max:
                        f = True
                        break
            if f:
                break
    else:
        re = [0, 0]
    return re



if __name__ == "__main__":
    # Add your test cases here

    print(solution(9, 34, [6, 6, 6, 8, 8, 8, 5, 5, 1]) == [8, 5])
    print(solution(9, 37, [9, 9, 9, 9, 6, 6, 6, 6, 13]) == [6, 9])
    print(solution(9, 40, [1, 11, 13, 12, 7, 8, 11, 5, 6]) == [0, 0])

第7题 创意标题匹配问题

问题描述

在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 bidword 对创意中的通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符)进行替换,用来提升广告投放体验。例如:“{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!”,会被替换成“帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!”。给定一个含有通配符的创意和n个标题,判断这句标题是否从该创意替换生成的。


测试样例

样例1:

输入:n = 4, template = "ad{xyz}cdc{y}f{x}e", titles = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
输出:"True,False,False,True"

样例2:

输入:n = 3, template = "a{bdc}efg", titles = ["abcdefg", "abefg", "efg"]
输出:"True,True,False"

样例3:

输入:n = 5, template = "{abc}xyz{def}", titles = ["xyzdef", "abcdef", "abxyzdef", "xyz", "abxyz"]
输出:"True,False,True,True,True"

问题分析

这个问题是关于字符串匹配和替换的算法问题。我们需要判断给定的标题是否可以通过替换创意中的通配符生成。下面是对这个问题的详细分析:

问题理解

  1. 创意(template):包含通配符的字符串,通配符用大括号 {} 表示,可以包含任意长度(包括0)的字符。
  2. 标题(titles):一组字符串,需要判断它们是否可以通过替换创意中的通配符生成。
  3. 通配符替换规则:创意中的每个通配符可以被任意长度的字符串替换,包括空字符串。

算法步骤

  1. 解析创意:首先,我们需要解析创意字符串,找出所有的通配符及其位置。
  2. 构建匹配规则:对于每个通配符,构建一个匹配规则,这个规则将允许在该位置插入任意长度的字符串。
  3. 匹配标题:对于每个标题,使用构建的匹配规则来检查它是否可以通过替换创意中的通配符生成。
    • 对于创意中的每个非通配符部分,检查标题中相应的部分是否匹配。
    • 对于创意中的每个通配符部分,检查标题中相应的部分是否可以插入任意长度的字符串。
  4. 输出结果:对于每个标题,输出是否可以通过替换创意生成的结果。

实现细节

  • 解析创意:遍历创意字符串,使用栈或其他数据结构来存储通配符的位置和长度。
  • 构建匹配规则:对于每个通配符,创建一个正则表达式或类似的匹配模式,允许任意字符出现任意次数。
  • 匹配标题:对于每个标题,使用构建的匹配规则进行匹配,检查是否完全匹配创意模板。
    • 如果标题长度比创意短,且差值正好是通配符的长度,那么可能是有效的替换。
    • 如果标题长度比创意长,检查额外的部分是否完全位于通配符的位置。

复杂度考虑

  • 时间复杂度:主要取决于匹配过程,对于每个标题,可能需要进行一次完整的字符串匹配,最坏情况下的时间复杂度为 O(n*m),其中 n 是标题的长度,m 是创意的长度。
  • 空间复杂度:主要取决于存储匹配规则的数据结构,最坏情况下可能需要存储所有通配符的信息,空间复杂度为 O(m)。

测试样例分析

  • 样例1:创意是 "ad{xyz}cdc{y}f{x}e",我们需要检查每个标题是否可以通过替换通配符生成。
    • "adcdcefdfeffe":匹配,因为可以替换成 "ad{xyz}cdc{y}f{x}e"。
    • "adcdcefdfeff":不匹配,因为缺少一个 "e"。
    • "dcdcefdfeffe":不匹配,因为缺少 "ad"。
    • "adcdcfe":匹配,因为可以替换成 "ad{xyz}cdc{y}f{x}e",其中 "xyz" 和 "x" 被替换为空字符串。
  • 样例2:创意是 "a{bdc}efg",我们需要检查每个标题是否可以通过替换通配符生成。
    • "abcdefg":匹配,因为 "{bdc}" 可以被替换成 "bdc"。
    • "abefg":匹配,因为 "{bdc}" 可以被替换成空字符串。
    • "efg":不匹配,因为缺少 "a" 和 "{bdc}ef"。
  • 样例3:创意是 "{abc}xyz{def}",我们需要检查每个标题是否可以通过替换通配符生成。
    • "xyzdef":匹配,因为 "{abc}" 可以被替换成空字符串。
    • "abcdef":不匹配,因为 "{abc}" 后面缺少 "xyz"。
    • "abxyzdef":匹配,因为 "{abc}" 可以被替换成 "ab"。
    • "xyz":匹配,因为 "{abc}" 和 "{def}" 都可以被替换成空字符串。
    • "abxyz":匹配,因为 "{def}" 可以被替换成空字符串。

这个问题的解决方案需要仔细的实现和测试,以确保正确匹配所有可能的标题替换情况。

解题代码

import re
def solution(n, template, titles):
    # Please write your code here
    result = []
    template = re.sub(pattern="{.*?}", repl=".*", string=template) # {}替换为匹配所有(非贪婪)
    template += "$" # 匹配字符串末尾
    for s in titles:
        print(re.match(pattern=template, string=s))
        if re.match(pattern=template, string=s) is not None:
            result.append("True")
        else:
            result.append("False")
        
    return ",".join(result)

if __name__ == "__main__":
    #  You can add more test cases here
    testTitles1 = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
    testTitles2 = ["CLSomGhcQNvFuzENTAMLCqxBdj", "CLSomNvFuXTASzENTAMLCqxBdj", "CLSomFuXTASzExBdj", "CLSoQNvFuMLCqxBdj", "SovFuXTASzENTAMLCq", "mGhcQNvFuXTASzENTAMLCqx"]
    testTitles3 = ["abcdefg", "abefg", "efg"]

    print(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1) == "True,False,False,True" )
    print(solution(6, "{xxx}h{cQ}N{vF}u{XTA}S{NTA}MLCq{yyy}", testTitles2) == "False,False,False,False,False,True" )
    print(solution(3, "a{bdc}efg", testTitles3) == "True,True,False" )

第8题 找出整型数组中占比超过一半的数

问题描述

小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。


测试样例

样例1:

输入:array = [1, 3, 8, 2, 3, 1, 3, 3, 3]
输出:3

样例2:

输入:array = [5, 5, 5, 1, 2, 5, 5]
输出:5

样例3:

输入:array = [9, 9, 9, 9, 8, 9, 8, 8]
输出:9

问题分析

这个问题是寻找“众数”的问题,即在一组数字中出现次数最多的数字。由于题目中指出某个数字的出现次数超过了数字总数的一半,我们可以确定这组数字中只有一个众数。

算法步骤

  1. 统计每个数字的出现次数:使用一个哈希表(或字典)来统计数组中每个数字出现的次数。
  2. 找到出现次数最多的数字:遍历哈希表,找到出现次数最多的数字。
  3. 验证出现次数是否超过一半:检查这个数字的出现次数是否大于数组长度的一半。如果是,则返回这个数字;如果不是,则返回“0”或“未找到”(根据题目要求)。

实现细节

  • 统计出现次数:遍历数组,对于每个数字,增加其在哈希表中的计数。
  • 找到众数:遍历哈希表,找到具有最大计数的数字。
  • 验证:检查这个数字的计数是否大于数组长度的一半。

复杂度考虑

  • 时间复杂度:O(n),其中 n 是数组的长度。这是因为我们需要遍历数组来统计每个数字的出现次数,然后再次遍历来找到出现次数最多的数字。
  • 空间复杂度:O(k),其中 k 是数组中不同数字的数量。在最坏的情况下,如果所有数字都不同,哈希表将包含与数组大小成比例的条目。

测试样例分析

  • 样例1:数组 [1, 3, 8, 2, 3, 1, 3, 3, 3] 中,数字 3 出现了 5 次,超过数组长度 9 的一半(4.5),所以输出是 3。
  • 样例2:数组 [5, 5, 5, 1, 2, 5, 5] 中,数字 5 出现了 5 次,超过数组长度 7 的一半(3.5),所以输出是 5。
  • 样例3:数组 [9, 9, 9, 9, 8, 9, 8, 8] 中,数字 9 出现了 5 次,超过数组长度 8 的一半(4),所以输出是 9。

这个问题的解决方案相对简单,因为题目中保证了存在一个数字的出现次数超过一半,所以我们不需要处理有多个众数的情况。

解题代码

def solution(array):
    # Edit your code here
    size=len(array)
    mp={}
    for i in array:
        mp[i]=mp.get(i,0)+1
    for k in mp:
        if mp.get(k)>size//2:
            return k
    return 0


if __name__ == "__main__":
    # Add your test cases here

    print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3)
    ```