「LeetCode」第 269 场周赛(上)

97 阅读1分钟

这是我参与11月更文挑战的第14天,活动详情查看2021最后一次更文挑战

链接

leetcode-cn.com/contest/wee…

题目

2089. 找出数组排序后的目标下标

统计

解析

由于最后要求的是排序之后target元素起始与末尾的序号,只需一遍统计数组中比target元素小的个数和target元素的个数即可。

代码

class Solution:
    def targetIndices(self, nums: List[int], target: int) -> List[int]:
        smallCount, targetCount = 0, 0
        for num in nums:
            if num < target:
                smallCount += 1
            elif num == target:
                targetCount += 1
        return [i for i in range(smallCount, smallCount + targetCount)]

排序后查找

解析

首先对数组进行升序排序,然后用直接遍历或二分查找的方式找出target元素的起止位置。
虽然数据规模n<=100不会对时间复杂度(O(nlogn)比O(n))造成特别大的影响,但是这种方式还是不如直接统计的方法方便简洁。

代码

class Solution:
    def targetIndices(self, nums: List[int], target: int) -> List[int]:
        nums.sort()
        if nums[0] > target or nums[-1] < target:
            return []
        else:
            left = 0
            n = len(nums)
            while left < n and nums[left] < target:
                left += 1
            right = left
            while right < n and nums[right] == target:
                right += 1
            return [ind for ind in range(left, right)]

2090. 半径为 k 的子数组平均值

滑动窗口

解析

这道题是一道较简单的滑动窗口题目,除去需要判断哪些位置取-1的情况外,基本上就是求对应位置左右范围内滑动窗口的元素和,每移动一次时窗口左右指针都移动一次即可。

代码

这份代码没有明显记录左右指针,因为左右指针所处的位置可以直接通过i和k计算出来

class Solution:
    def getAverages(self, nums: List[int], k: int) -> List[int]:
        n = len(nums)
        ans = []
        currSum = sum(nums[0 : (2*k + 1)])
        for i, num in enumerate(nums):
            if i - k < 0 or i + k >= n:
                ans.append(-1)
            else:
                ans.append(currSum // (2*k + 1))
                if i+k+1 < n:
                    currSum += nums[i+k+1] - nums[i-k]
        return ans

前缀和

解析

判断-1的情况和滑动窗口的思路类似,区别在于前缀和提前求和、后续能在O(1)时间将范围和求出

代码

class Solution:
    def getAverages(self, nums: List[int], k: int) -> List[int]:
        n = len(nums)
        prevSum = [0] * (n+1)
        for i in range(n):
            prevSum[i+1] = nums[i] + prevSum[i]
        ans = []
        for i in range(n):
            if i - k < 0 or i + k >= n:
                ans.append(-1)
            else:
                ans.append((prevSum[i + k + 1] - prevSum[i - k]) // (2*k + 1))
        return ans