【力扣】第302场周赛记录

6120. 数组能形成多少数对

链接: 数组能形成多少数对
描述:

给你一个下标从 0 开始的整数数组 nums 。在一步操作中,你可以执行以下步骤:

  • 从 nums 选出 两个 相等的 整数
  • 从 nums 中移除这两个整数,形成一个 数对

请你在 nums 上多次执行此操作直到无法继续执行。

返回一个下标从 0 开始、长度为 2 的整数数组 answer 作为答案,其中 answer[0] 是形成的数对数目,answer[1] 是对 nums 尽可能执行上述操作后剩下的整数数目。

个人思路:
用一个Counter遍历数组,每次添加判断一下当前数字的数量是否=2,如果是就更新answer同时把Counter[num]置0

class Solution(object):
    def numberOfPairs(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        ans = [0, 0]
        ans[1] = len(nums)
        m = collections.Counter()
        for num in nums:
            m[num] += 1
            if m[num] == 2:
                ans[0] += 1
                ans[1] -= 2
                m[num] = 0
        return ans

Better
待更新

6164. 数位和相等数对的最大和

链接: 数位和相等数对的最大和
描述:

给你一个下标从 0 开始的数组 nums ,数组中的元素都是 整数。请你选出两个下标i ji != j),且 nums[i] 的数位和 与 nums[j] 的数位和相等。

请你找出所有满足条件的下标ij,找出并返回 nums[i] + nums[j] 可以得到的 最大值 。

个人思路:
因为是最大和,我想先降序然后再遍历构建数位和相等的哈希表(其中key = 数位和value = list[])这样能保证哈希表里的数组也都是降序,这样在找最大和的时候只需要判断每个数组的头两个元素和。

class Solution:
    def maximumSum(self, nums: List[int]) -> int:
        # 计算数位和函数:从个位开始依次取
        def calculate_sum(num):
            _sum = 0
            while num:
                _sum += (num % 10)
                num = num // 10
            return _sum
        
        
        # 先把nums降序
        nums.sort(reverse=True)
        
        # 构建数位和相等的哈希表
        hashmap = collections.defaultdict(list)
        for num in nums:
            key = calculate_sum(num)
            hashmap[key].append(num)
  
            
        # 遍历哈希表的key,对数目大于2的key进行求和,维护一个max
        ans = -1
        for key in hashmap:
            if len(hashmap[key]) >= 2:
                ans = max(ans, hashmap[key][0] + hashmap[key][1])
                
        return ans        

Better:
待更新

6121. 裁剪数字后查询第 K 小的数字

链接: 裁剪数字后查询第 K 小的数字
描述:

给你一个下标从 0 开始的字符串数组nums,其中每个字符串 长度相等 且只包含数字。

再给你一个下标从 0 开始的二维整数数组 queries ,其中queries[i] = [ki, trimi]。对于每个queries[i] ,你需要:

  • nums中每个数字 裁剪 到剩下 最右边 trimi 个数位。
  • 在裁剪过后的数字中,找到nums中第ki小数字对应的 下标。如果两个裁剪后数字一样大,那么下标 更小 的数字视为更小的数字。
  • nums中每个数字恢复到原本字符串。

请你返回一个长度与queries相等的数组 answer,其中answer[i]是第i次查询的结果。

提示:

  • 裁剪到剩下 x 个数位的意思是不断删除最左边的数位,直到剩下 x 个数位。
  • nums 中的字符串可能会有前导 0 。

个人思路:

  1. 先用crop_str(array, n)裁剪,输出裁剪后的数组sub_arr[],其中sub_arr里的元素是(num, index),裁剪后的数字和它的下标;
  2. sub_arr进行sort()排序
  3. 输出sub[k-1]对应的下标

刚开始不知道把下标也作为数组的元素之一,导致后面甚至使用到了堆排序来pop前k个,不过这样没办法保证遇到相同元素时输出的下标是正确的。

class Solution(object):
    def smallestTrimmedNumbers(self, nums, queries):
        """
        :type nums: List[str]
        :type queries: List[List[int]]
        :rtype: List[int]
        """
        # 裁剪函数
        def crop_str(array, n):
            sub_arr = []
            for i, ch in enumerate(array):
                sub_arr.append((int(ch[-n:]), i))
            return sub_arr


        res = []
        for query in queries:
            arr = crop_str(nums, query[1])
            arr.sort() # 排序
            res.append(arr[query[0]-1][1]) # 输出第k小的元素下标

        return res

Better:
评论区扣到的,思路差不多(大概)不过处理的更好更快更精简。
还看到有用基数排序的,我还没学到代码实现所以先不放了。

class Solution(object):
    def smallestTrimmedNumbers(self, nums, queries):
        """
        :type nums: List[str]
        :type queries: List[List[int]]
        :rtype: List[int]
        """
        ans=[]
        for k,trim in queries:
            tmp=[(num[-trim:],i) for i,num in enumerate(nums)]
            tmp.sort()
            ans.append(tmp[k-1][1])
        return ans

6122. 使数组可以被整除的最少删除次数

题目链接
描述:

给你两个正整数数组 nums numsDivide 。你可以从nums中删除任意数目的元素。

请你返回使nums中 最小 元素可以整除 numsDivide 中所有元素的 最少 删除次数。如果无法得到这样的元素,返回 -1

如果y % x == 0,那么我们说整数 x 整除 y

示例 1:

输入:nums = [2,3,2,4,3], numsDivide = [9,6,9,3,15]
输出:2
解释:
[2,3,2,4,3] 中最小元素是 2 ,它无法整除 numsDivide 中所有元素。
我们从 nums 中删除 2 个大小为 2 的元素,得到 nums = [3,4,3] 。
[3,4,3] 中最小元素为 3 ,它可以整除 numsDivide 中所有元素。
可以证明 2 是最少删除次数。

思路:
求最大公因数,先排序,从小到大找到第一个能整除g的元素x,所有小于x的元素都需要删除。

class Solution:
    def minOperations(self, nums: List[int], numsDivide: List[int]) -> int:
        g = reduce(gcd, numsDivide)
        nums.sort()
        return next((i for i, x in enumerate(nums) if g % x == 0), -1)

这个是评论区扣的,当时时间问题没有写到这一题
回头再来细看。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值