[Leetcode Weekly Contest]195

链接:LeetCode

[Leetcode]5448. 判断路径是否相交

给你一个字符串 path,其中\(path[i]\)的值可以是 'N'、'S'、'E' 或者 'W',分别表示向北、向南、向东、向西移动一个单位。
机器人从二维平面上的原点 (0, 0) 处开始出发,按 path 所指示的路径行走。
如果路径在任何位置上出现相交的情况,也就是走到之前已经走过的位置,请返回 True ;否则,返回 False 。

利用集合的性质,每次判断是否在已走过的位置即可。

class Solution:
    def isPathCrossing(self, path: str) -> bool:
        now = (0,0)
        al_path = set([now])
        for p in path:
            s,t = now
            if p == 'N':
                s+=1
            elif p == 'S':
                s-=1
            elif p=='E':
                t+=1
            else:
                t-=1
            now = (s,t)
            if now in al_path:return True
            al_path.add(now)
        return False

[Leetcode]5449. 检查数组对是否可以被 k 整除

给你一个整数数组 arr 和一个整数 k ,其中数组长度是偶数,值为 n 。现在需要把数组恰好分成 n / 2 对,以使每对数字的和都能够被 k 整除。如果存在这样的分法,请返回 True ;否则,返回 False 。

统计各余数的个数,然后进行配对。当非0余数能够配对时,则说明存在这样的分法,否在不存在。

import collections
class Solution:
    def canArrange(self, arr: List[int], k: int) -> bool:
        if sum(arr)%k!=0:
            return False
        arr = [a%k for a in arr]
        counter = collections.Counter(arr)
        for num in counter:
            if num!=0 and counter[num]!=counter[k-num]:
                return False
        return True

[Leetcode]5450. 满足条件的子序列数目

给你一个整数数组 nums 和一个整数 target 。请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。
由于答案可能很大,请将结果对 10^9 + 7 取余后返回。

排序加双指针,每次找到以\(nums[i]\)为最小值的子序列数目,以\(nums = [3,5,6,7], target = 9\)为例,设定左右指针left,right,当3为非空子序列最小值,判断\(nums[left]+nums[right]\)与target关系:

  • \(nums[left]+nums[right]>target\),说明左右指针值无法构成合理子序列,则right-1,继续寻找;
  • \(nums[left]+nums[right]<=target\),说明左右指针值可以构成合理子序列,并且最小值为\(nums[left]\)的子序列中可以存在\(nums[left+1:right+1]\)的任一数值,一共有\(2**(right-left)\)种可能。
class Solution:
    def numSubseq(self, nums: List[int], target: int) -> int:
        nums.sort()
        mod = int(10**9+7)
        res = 0
        l, r = 0, len(nums)-1
        while l<=r:
            if nums[l]+nums[r]>target:
                r -= 1
            else:
                res = (res + (1<<(r-l)))%mod
                l+=1
        return res

[Leetcode]5451. 满足不等式的最大值

给你一个数组 points 和一个整数 k 。数组中每个元素都表示二维平面上的点的坐标,并按照横坐标 x 的值从小到大排序。也就是说\(points[i] = [xi, yi]\),并且在 1 <= i < j <= points.length 的前提下, xi < xj 总成立。请你找出 yi + yj + |xi - xj| 的 最大值,其中 |xi - xj| <= k 且 1 <= i < j <= points.length。
题目测试数据保证至少存在一对能够满足 |xi - xj| <= k 的点。

单调队列。时间复杂度O(N)

typedef pair<int, int> PII;
class Solution {
public:
    int findMaxValueOfEquation(vector<vector<int>>& points, int k) {
        deque<PII> dq;
        dq.push_back({points[0][0], points[0][1] - points[0][0]});
        int ans = -2e9;
        for(int i = 1; i < points.size(); i ++) {

            while (dq.size() && points[i][0] - dq.front().first > k) dq.pop_front();
            if (dq.size()) ans = max(ans, dq.front().second + points[i][0] + points[i][1]);
            while (dq.size() && dq.back().second <= points[i][1] - points[i][0]) dq.pop_back();
            dq.push_back({points[i][0], points[i][1] - points[i][0]});
        }
        return ans;
    }
};

参考:
Leetcode

posted @ 2020-06-28 21:24  Jamest  阅读(152)  评论(0编辑  收藏  举报