leetcode周赛-230

5689. 统计匹配检索规则的物品数量

AC

题目

给你一个数组 items ,其中 items[i] = [typei, colori, namei] ,描述第 i 件物品的类型、颜色以及名称。

另给你一条由两个字符串 ruleKey 和 ruleValue 表示的检索规则。

如果第 i 件物品能满足下述条件之一,则认为该物品与给定的检索规则 匹配 :

ruleKey == "type" 且 ruleValue == typei 。
ruleKey == "color" 且 ruleValue == colori 。
ruleKey == "name" 且 ruleValue == namei 。

统计并返回 匹配检索规则的物品数量 。

示例 1:

输入:items = [["phone","blue","pixel"],["computer","silver","lenovo"],["phone","gold","iphone"]], ruleKey = "color", ruleValue = "silver"
输出:1
解释:只有一件物品匹配检索规则,这件物品是 ["computer","silver","lenovo"] 。

示例 2:

输入:items = [["phone","blue","pixel"],["computer","silver","phone"],["phone","gold","iphone"]], ruleKey = "type", ruleValue = "phone"
输出:2
解释:只有两件物品匹配检索规则,这两件物品分别是 ["phone","blue","pixel"] 和 ["phone","gold","iphone"] 。注意,["computer","silver","phone"] 未匹配检索规则。

提示:

1 <= items.length <= 10^4
1 <= typei.length, colori.length, namei.length, ruleValue.length <= 10
ruleKey 等于 "type"、"color" 或 "name"
所有字符串仅由小写字母组成

解题思路

简单题,根据ruleKey确定是item的第几个索引,然后对照找相同的即可。时间复杂度 o ( i t e m s . l e n g t h ) o(items.length) o(items.length)

代码

class Solution:
    def countMatches(self, items: List[List[str]], ruleKey: str, ruleValue: str) -> int:
        ans = 0
        rule_index = {'type': 0, 'color': 1, 'name': 2}[ruleKey]
        for each_item in items:
            if each_item[rule_index] == ruleValue:
                ans += 1
        return ans

5690. 最接近目标价格的甜点成本

AC

题目

你打算做甜点,现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则:

必须选择 一种 冰激凌基料。
可以添加 一种或多种 配料,也可以不添加任何配料。
每种类型的配料 最多两份 。
给你以下三个输入:

baseCosts ,一个长度为 n 的整数数组,其中每个 baseCosts[i] 表示第 i 种冰激凌基料的价格。
toppingCosts,一个长度为 m 的整数数组,其中每个 toppingCosts[i] 表示 一份 第 i 种冰激凌配料的价格。
target ,一个整数,表示你制作甜点的目标价格。
你希望自己做的甜点总成本尽可能接近目标价格 target 。

返回最接近 target 的甜点成本。如果有多种方案,返回 成本相对较低 的一种。

示例 1:

输入:baseCosts = [1,7], toppingCosts = [3,4], target = 10
输出:10
解释:考虑下面的方案组合(所有下标均从 0 开始):
- 选择 1 号基料:成本 7
- 选择 1 份 0 号配料:成本 1 x 3 = 3
- 选择 0 份 1 号配料:成本 0 x 4 = 0
总成本:7 + 3 + 0 = 10 。

示例 2:

输入:baseCosts = [2,3], toppingCosts = [4,5,100], target = 18
输出:17
解释:考虑下面的方案组合(所有下标均从 0 开始):
- 选择 1 号基料:成本 3
- 选择 1 份 0 号配料:成本 1 x 4 = 4
- 选择 2 份 1 号配料:成本 2 x 5 = 10
- 选择 0 份 2 号配料:成本 0 x 100 = 0
总成本:3 + 4 + 10 + 0 = 17 。不存在总成本为 18 的甜点制作方案。

示例 3:

输入:baseCosts = [3,10], toppingCosts = [2,5], target = 9
输出:8
解释:可以制作总成本为 8 和 10 的甜点。返回 8 ,因为这是成本更低的方案。

示例 4:

输入:baseCosts = [10], toppingCosts = [1], target = 1
输出:10
解释:注意,你可以选择不添加任何配料,但你必须选择一种基料。

提示:

n == baseCosts.length
m == toppingCosts.length
1 <= n, m <= 10
1 <= baseCosts[i], toppingCosts[i] <= 10^4
1 <= target <= 10^4

解题思路

DFS(因为n, m都比较小)
首先考虑baseCosts,对每种baseCosts都重复。DFStoppingCosts,用当前index对应的topping1次或者2次,把做出来的成本都保存下来。全部遍历完后,从所有成本中找出最接近target的即可

代码

class Solution:
    def closestCost(self, baseCosts: List[int], toppingCosts: List[int], target: int) -> int:
        n, m = len(baseCosts), len(toppingCosts)
        ans = set()
        def helper(topping_begin: int, target: int) -> None:
            if target < 0:
                return
            for topping_index in range(topping_begin, m):
                ans.add(target)
                ans.add(target - toppingCosts[topping_index])
                ans.add(target - 2 * toppingCosts[topping_index])
                helper(topping_index + 1, target - toppingCosts[topping_index])
                helper(topping_index + 1, target - 2 * toppingCosts[topping_index])
        for each_base in baseCosts:
            if target - each_base <= 0:
                ans.add(target - each_base)
            else:
                helper(0, target - each_base)
        ans = sorted(ans)
        abs_min = min(map(abs, ans))
        if abs_min in ans:
            return target - abs_min
        return target + abs_min           

5691. 通过最少操作次数使数组的和相等

AC

题目

给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。

每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包含 1 和 6)。

请你返回使 nums1 中所有数的和与 nums2 中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1 。

示例 1:

输入:nums1 = [1,2,3,4,5,6], nums2 = [1,1,2,2,2,2]
输出:3
解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。
- 将 nums2[0] 变为 6 。 nums1 = [1,2,3,4,5,6], nums2 = [6,1,2,2,2,2] 。
- 将 nums1[5] 变为 1 。 nums1 = [1,2,3,4,5,1], nums2 = [6,1,2,2,2,2] 。
- 将 nums1[2] 变为 2 。 nums1 = [1,2,2,4,5,1], nums2 = [6,1,2,2,2,2] 。

示例 2:

输入:nums1 = [1,1,1,1,1,1,1], nums2 = [6]
输出:-1
解释:没有办法减少 nums1 的和或者增加 nums2 的和使二者相等。

示例 3:

输入:nums1 = [6,6], nums2 = [1]
输出:3
解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。
- 将 nums1[0] 变为 2 。 nums1 = [2,6], nums2 = [1] 。
- 将 nums1[1] 变为 2 。 nums1 = [2,2], nums2 = [1] 。
- 将 nums2[0] 变为 4 。 nums1 = [2,2], nums2 = [4] 。

提示:

1 <= nums1.length, nums2.length <= 10^5
1 <= nums1[i], nums2[i] <= 6

解题思路

思路理顺了其实比较简单的,贪心的思路。
首先,因为可以选择任意数组进行变动,所以其实2个数组之间没有明显的区别。为了简单起见,把和比较大的数组记为larger,比较小的数组记为smaller,两者之间和的差距记为gap,因为gap的定义是大的减小的,所以gap始终是正的。

对于larger而言,其中的数字需要向小变化,所以larger[i] - 1体现的是当前数字能做出的最大贡献。类似地,对smaller而言,由于数字需要向大变化,所以6 - smaller[i]体现的是贡献。

largersmaller的每个数字的贡献都算出来,然后从大到小累加贡献,当贡献>= gap时就可以了。
因为这里其实是每个最大能做出的贡献,其实也可以选择不做这么多贡献,比如gap = 2larger中有一个数字是6,则6对应的最大贡献是5,那么其实6可以不用贡献5(即变到1),而是直接贡献2(即变到4)即可

时间复杂度为o(nums1.length + nums2.length)

代码

class Solution:
    def minOperations(self, nums1: List[int], nums2: List[int]) -> int:
        sum1, sum2 = sum(nums1), sum(nums2)
        if sum1 > sum2:
            larger = nums1
            smaller = nums2
        elif sum1 < sum2:
            larger = nums2
            smaller = nums1
        else:
            return 0
        gap = sum(larger) - sum(smaller)
        contribs = [item - 1 for item in larger if item - 1 > 0] + [6 - item for item in smaller if 6 - item > 0]
        contribs.sort()
        cnt = 0
        for item in contribs[::-1]:
            gap -= item
            cnt += 1
            if gap <= 0:
                return cnt
        return -1

5692. 车队 II

完全没思路……

题目

在一条单车道上有 n 辆车,它们朝着同样的方向行驶。给你一个长度为 n 的数组 cars ,其中 cars[i] = [positioni, speedi] ,它表示:

  • p o s i t i o n i position_i positioni 是第 i 辆车和道路起点之间的距离(单位:米)。题目保证 p o s i t i o n i position_i positioni < p o s i t i o n i + 1 position_{i+1} positioni+1
  • s p e e d i speed_i speedi 是第 i 辆车的初始速度(单位:米/秒)。

简单起见,所有车子可以视为在数轴上移动的点。当两辆车占据同一个位置时,我们称它们相遇了。一旦两辆车相遇,它们会合并成一个车队,这个车队里的车有着同样的位置和相同的速度,速度为这个车队里 最慢 一辆车的速度。

请你返回一个数组 answer ,其中 answer[i] 是第 i 辆车与下一辆车相遇的时间(单位:秒),如果这辆车不会与下一辆车相遇,则 answer[i] 为 -1 。答案精度误差需在 1 0 − 5 10^{-5} 105 以内。

示例 1:

输入:cars = [[1,2],[2,1],[4,3],[7,2]]
输出:[1.00000,-1.00000,3.00000,-1.00000]
解释:经过恰好 1 秒以后,第一辆车会与第二辆车相遇,并形成一个 1 m/s 的车队。经过恰好 3 秒以后,第三辆车会与第四辆车相遇,并形成一个 2 m/s 的车队。

示例 2:

输入:cars = [[3,4],[5,4],[6,3],[9,1]]
输出:[2.00000,1.00000,1.50000,-1.00000]

提示:

1 <= cars.length <= 10^5
1 <= position[i], speed[i] <= 10^6
position[i] < position[i+1]

解题思路

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值