22.10.23 LC周赛 数组公约数、中位数贪心、奇偶邻项交换

22.10.23 LC周赛 数组公约数、中位数贪心、奇偶邻项交换

   这次周赛仍然只做出2道题,而且第二题还查了一下 如何计算数组的最大公约数 委实菜的不行啊! 还要保持激昂的精神继续努力啊!这次学到不少知识,分享记录一下,如果朋友看得喜欢麻烦点赞收藏哦。

6214. 判断两个事件是否存在冲突(反向思维)

题目链接:6214. 判断两个事件是否存在冲突
题目大意:给你两个字符串数组 event1 和 event2 ,表示发生在同一天的两个闭区间时间段事件,其中:

  • event1 = [startTime1, endTime1] 且event2 = [startTime2, endTime2]
    事件的时间为有效的 24 小时制且按 HH:MM 格式给出。
    当两个事件存在某个非空的交集时(即,某些时刻是两个事件都包含的),则认为出现 冲突 。
    如果两个事件之间存在冲突,返回 true ;否则,返回 false 。

例如:

输入:event1 = ["01:15","02:00"], event2 = ["02:00","03:00"]
输出:true
解释:两个事件在 2:00 出现交集。

输入:event1 = ["01:00","02:00"], event2 = ["01:20","03:00"]
输出:true
解释:两个事件的交集从 01:20 开始,到 02:00 结束。

输入:event1 = ["10:00","11:00"], event2 = ["14:00","15:00"]
输出:false
解释:两个事件不存在交集。
  • 解题思路:反向考虑 会简单很多,去找满足要求的区间。数组的最大公因数、最小公倍数可以参考这篇 blog。
  • 时间复杂度: O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( 1 ) O(1) O(1)
class Solution:
    def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
		
		# 一行解决
		return not(event1[0]>event2[1] or event2[0]>event1[1])
		
		# 正向考虑
		""" 
        a1,a2,b1,b2 = event1[0],event1[1],event2[0],event2[1]
        h1,c1 = a1.split(':')
        h2,c2 = a2.split(':')
        h3,c3 = b1.split(':')
        h4,c4 = b2.split(':')
        if h1 <= h3 or (h1==h3 and c1<=c3):
            if h3 < h2 or (h3==h2 and c3<=c2):
                return True
            else:
                return False
        else:
            if h1 < h4 or (h1==h4 and c1<=c4):
                return True
            else:
                return False
		"""

6224. 最大公因数等于 K 的子数组数目(连续子数组最大公因数)

题目链接:6224. 最大公因数等于 K 的子数组数目
题目大意:给你一个整数数组 nums 和一个整数 k ,请你统计并返回 nums 的子数组中元素的最大公因数等于 k 的子数组数目。子数组 是数组中一个连续的非空序列。数组的最大公因数 是能整除数组中所有元素的最大整数。

例如:

输入:nums = [9,3,1,2,6,3], k = 3
输出:4
解释:nums 的子数组中,以 3 作为最大公因数的子数组如下:
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]

输入:nums = [4], k = 7
输出:0
解释:不存在以 7 作为最大公因数的子数组。
  • 解题思路:有点动态规划的思想在里面,主要是双重循环连续子数组的最大公因数判断
  • 时间复杂度:构造函数复杂度为 O ( N 2 log ⁡ U ) O(N^2 \log U) O(N2logU) ,N为数组nums长度, U = m a x ( n u m s ) U=max(nums) U=max(nums)
  • 空间复杂度:构造函数复杂度为 O ( 1 ) O(1) O(1)
class Solution:
    def subarrayGCD(self, nums: List[int], k: int) -> int:
        ans = 0
        n = len(nums)
        for i in range(n):
            if nums[i] % k ==0:
                g = nums[i]
                for j in range(i,n):        
                    g = gcd(g,nums[j])
                    # print(g)
                    if g == k: ans += 1
            else:
                continue
        return ans

6216. 使数组相等的最小开销(中位数贪心)

题目链接:6216. 使数组相等的最小开销
题目大意:给你两个下标从 0 开始的数组 nums 和 cost ,分别包含 n 个 正 整数。
你可以执行下面操作 任意 次:

  • 将 nums 中 任意 元素增加或者减小 1 。
  • 对第 i 个元素执行一次操作的开销是 cost[i] 。

请你返回使 nums 中所有元素 相等 的 最少 总开销。

输入:nums = [1,3,5,2], cost = [2,3,1,14]
输出:8
解释:我们可以执行以下操作使所有元素变为 2- 增加第 0 个元素 1 次,开销为 2- 减小第 1 个元素 1 次,开销为 3- 减小第 2 个元素 3 次,开销为 1 + 1 + 1 = 3 。
总开销为 2 + 3 + 3 = 8 。这是最小开销。

输入:nums = [2,2,2,2,2], cost = [4,2,8,1,3]
输出:0
解释:数组中所有元素已经全部相等,不需要执行额外的操作。
  • 解题思路:中位数 贪心 这类题目 原来也有固定技巧啊! 我那时候一直在想 该怎么整,揪准 中位数 这个关键点 此题便搞出来了。
  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),N为数组 nums \textit{nums} nums长度
  • 空间复杂度: O ( N ) O(N) O(N)
class Solution:
    # 中位数贪心
    def minCost(self, nums: List[int], cost: List[int]) -> int:
        a = sorted(zip(nums,cost))
        s,mid = 0,sum(cost)//2
        for x,v in a:
            s += v
            if s > mid:
                return sum(abs(x-y)*c for y,c in a) 

6217. 使数组相似的最少操作次数(奇偶邻项变化)

题目链接:6217. 使数组相似的最少操作次数
题目大意:给你两个正整数数组 nums 和 target ,两个数组长度相等。
在一次操作中,你可以选择两个 不同 的下标 i 和 j ,其中 0 <= i, j < nums.length ,并且:

  • 令 nums[i] = nums[i] + 2 且 令 nums[j] = nums[j] - 2 。

如果两个数组中每个元素出现的频率相等,我们称两个数组是 相似 的。
请你返回将 nums 变得与 target 相似的最少操作次数。测试数据保证 nums 一定能变得与 target 相似。

输入:nums = [8,12,6], target = [2,14,10]
输出:2
解释:可以用两步操作将 nums 变得与 target 相似:
- 选择 i = 0 和 j = 2 ,nums = [10,12,4]- 选择 i = 1 和 j = 2 ,nums = [10,14,2]2 次操作是最少需要的操作次数。

输入:nums = [1,2,5], target = [4,1,3]
输出:1
解释:一步操作可以使 nums 变得与 target 相似:
- 选择 i = 1 和 j = 2 ,nums = [1,4,3] 。

输入:nums = [1,1,1,1,1], target = [1,1,1,1,1]
输出:0
解释:数组 nums 已经与 target 相似。
  • 解题思路:3步走
    1. 由 +1 -1 得知 邻项交换法:大的匹配大的,小的匹配小的
    2. +2 -2 不会改变数字的奇偶性
    3. 排序匹配。
  • 时间复杂度: O ( N log ⁡ N ) O(N \log N) O(NlogN),N为数组 nums \textit{nums} nums长度
  • 空间复杂度: O ( 1 ) O(1) O(1)
class Solution:
    def makeSimilar(self, nums: List[int], target: List[int]) -> int:
        nums.sort()
        target.sort()
        # 这里 j 的使用直接将奇偶 给分开了 将空间复杂度压至1
        ans,j = 0,[0,0]
        for x in nums:
            p = x%2
            while target[j[p]] % 2 != p:
                j[p] += 1
            ans += abs(x-target[j[p]])
            j[p] += 1
        return ans // 4

总结

   努力 奋斗!通过2道,还 无耻地百度了 好多次,还是要做题和思考啊,积极的心态去持续学下去,必须养成做笔记的好习惯,这样的复盘不仅能加深记忆,而且也利于以后的回顾总结。最后,唠一句,枸杞对单身的人真是一种快乐的折磨,哎~

你可能感兴趣的:(python算法学习,LC分类题型汇总,leetcode,算法,贪心算法,python,最大公约数)