LeetCode周赛第195场周赛
Posted lalal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode周赛第195场周赛相关的知识,希望对你有一定的参考价值。
一、1496. 判断路径是否相交:
给你一个字符串 path,其中 path[i] 的值可以是 ‘N‘、‘S‘、‘E‘ 或者 ‘W‘,分别表示向北、向南、向东、向西移动一个单位。
机器人从二维平面上的原点 (0, 0) 处开始出发,按 path 所指示的路径行走。
如果路径在任何位置上出现相交的情况,也就是走到之前已经走过的位置,请返回 True ;否则,返回 False 。
示例:
输入:path = "NESWW" 输出:true 解释:该路径经过原点两次。
分析:
? 一开始看错题目,如果只需要判断是否能回到原点,可以利用类似栈的思想。如果需要判断所有走过的位置,也只需要使用字典或者数组记录就可以解决。
代码(Python):
class Solution:
def isPathCrossing(self, path: str) -> bool:
if not path:
return False
n = len(path)
pos = defaultdict(bool)
pos[(0, 0)] = True
vert = 0
hor = 0
for val in path:
if val == "N":
vert += 1
elif val == "E":
hor += 1
elif val == "S":
vert -= 1
elif val == "W":
hor -= 1
if pos[(hor, vert)]:
return True
else:
pos[(hor, vert)] = True
return False
二、1497. 检查数组对是否可以被 k 整除:
给你一个整数数组 arr
和一个整数 k
,其中数组长度是偶数,值为 n
。
现在需要把数组恰好分成 n / 2
对,以使每对数字的和都能够被 k
整除。
如果存在这样的分法,请返回 True ;否则,返回 False 。
示例:
输入:arr = [1,2,3,4,5,10,6,7,8,9], k = 5
输出:true
解释:划分后的数字对为 (1,9),(2,8),(3,7),(4,6) 以及 (5,10) 。输入:arr = [1,2,3,4,5,6], k = 7
输出:true
解释:划分后的数字对为 (1,6),(2,5) 以及 (3,4) 。
分析:
? 如果我们暴力枚举每一对组合,并且判断是否被k整除,时间复杂度会相当高。原因之一:例如我们选择1,我们无法非常明显的找到我们所需要的配对元素。二:对于多个配对的元素,如何进行选择?
解决:
一:
? 1可以与4, 9相加后被5整除。但是并不直观,如果我们对数组中每个元素 先对k取余。
(1 o 1, 4 o 4, 9 o 4)
这样就可以通过两个余数相加,是否为k或0来判断,更加直观。
二:
? 如上例,1可以与两个数配对。而可能只有一个数才可以使所有数满足要求。如何进行选择?
将余数作为键,存储所有值的个数,进行匹配即可。
代码(Python):
class Solution:
def canArrange(self, arr: List[int], k: int) -> bool:
mod = collections.Counter(num % k for num in arr)
for t, occ in mod.items():
if t > 0 and (k - t not in mod or mod[k - t] != occ):
return False
return mod[0] % 2 == 0
三、1498. 满足条件的子序列数目:
给你一个整数数组 nums 和一个整数 target 。
请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。
由于答案可能很大,请将结果对 10^9 + 7 取余后返回。
示例:
输入:nums = [3,5,6,7], target = 9
输出:4
解释:有 4 个子序列满足该条件。
[3] -> 最小元素 + 最大元素 <= target (3 + 3 <= 9)
[3,5] -> (3 + 5 <= 9)
[3,5,6] -> (3 + 6 <= 9)
[3,6] -> (3 + 6 <= 9)输入:nums = [3,3,6,8], target = 10
输出:6
解释:有 6 个子序列满足该条件。(nums 中可以有重复数字)
[3] , [3] , [3,3], [3,6] , [3,6] , [3,3,6]
分析:
? 看到数组,最大值、最小值、和这些关键字,就可以想到利用滑动窗口解决问题了。
? 首先进行排序,确保数组元素升序。接着从right指针开始寻找符合要求的第一个位置,接着往右移动,不断累加计算。
代码(Python):
class Solution:
def numSubseq(self, nums: List[int], target: int) -> int:
nums.sort()
if nums[0] * 2 > target:
return 0
n = len(nums)
ans = 0
left, right = 0, n - 1
while right >= left:
if nums[left] + nums[right] <= target:
ans += 2 ** (right - left)
left += 1
else:
right -= 1
return ans % (10 ** 9 + 7)
以上是关于LeetCode周赛第195场周赛的主要内容,如果未能解决你的问题,请参考以下文章