英雄星球六月集训 LeetCode解题日报] 0601 数组

一、 327. 所有奇数长度子数组的和

链接: 1588. 所有奇数长度子数组的和

1. 题目描述

给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。

子数组 定义为原数组中的一个连续子序列。

请你返回 arr 中 所有奇数长度子数组的和

2. 思路分析

求数组中所有奇数长度子数组的和的和。
分析每个元素在几个奇数长度子数组里,乘一下,加起来就行。
a[i] 如果在奇数长度子数组里,那么它左右两边的数字个数和一定是偶数,左右同为奇或偶,分别分析即可。
a[i]在原数组中左边有l=i个数,右边有r=n-i-1个数:
奇数个数: 左边(l+1)//2,右边(r+1)//2
偶数个数: 左边 l//2+1, 右边r//2+1
最坏时间复杂度O(n)
40 ms Python3 89.19%

3. 代码实现

class Solution:
    def sumOddLengthSubarrays(self, arr: List[int]) -> int:
        n = len(arr)
        s = 0
        for i in range(n):
            l,r =i ,n-i-1
            l1,r1 = (l+1)//2,(r+1)//2
            l2,r2 = l//2+1,r//2+1
            s += arr[i] * (l1*r1 + l2*r2)
        return s

二、 1848. 到目标元素的最小距离

链接: 1848. 到目标元素的最小距离

1. 题目描述

给你一个整数数组 nums (下标 从 0 开始 计数)以及两个整数 target 和 start ,请你找出一个下标 i ,满足 nums[i] == target 且 abs(i - start) 最小化 。注意:abs(x) 表示 x 的绝对值。

返回 abs(i - start) 。

题目数据保证 target 存在于 nums 中。

2. 思路分析

从数组中找指定的数距离pos下标最近的下标。
遍历
最坏时间复杂度O(n)
40 ms Python3 55.06%

3. 代码实现

class Solution:
    def getMinDistance(self, nums: List[int], target: int, start: int) -> int:
        d = len(nums) + 1
        for i,n in enumerate(nums):
            if nums[i] == target:
                d = min(d,abs(i-start))        
        return d

三、 1652. 拆炸弹

链接: 1652. 拆炸弹

1. 题目描述

你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。

为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。

如果 k > 0 ,将第 i 个数字用 接下来 k 个数字之和替换。
如果 k < 0 ,将第 i 个数字用 之前 k 个数字之和替换。
如果 k == 0 ,将第 i 个数字用 0 替换。
由于 code 是循环的, code[n-1] 下一个元素是 code[0] ,且 code[0] 前一个元素是 code[n-1] 。

给你 循环 数组 code 和整数密钥 k ,请你返回解密后的结果来拆除炸弹

2. 思路分析

按照题目规则处理每个数,把当前数替换为旁边k个数的和。
由于可能向前走,且|k|<n,为了方便处理直接把原数组乘3,处理中间那段就不用管下标问题了。
区间和就算个前缀和。
最坏时间复杂度O(n)

32 ms, Python3 96.76%

3. 代码实现

class Solution:
    def decrypt(self, code: List[int], k: int) -> List[int]:
        n = len(code)
        new = code[:]*3
        pre = list(accumulate(new,initial=0))  # 前缀数组,sum[i,j] = pre[j+1]-pre[i] 
        for i in range(n):
            new_i = i + n
            if k == 0:
                code[i] = 0
            elif k > 0:
                code[i] = pre[new_i+1+k] - pre[new_i+1]
            else:
                code[i] = pre[new_i] - pre[new_i+k]        
        return code

四、 1640. 能否连接形成数组

链接: 1640. 能否连接形成数组

1. 题目描述

给你一个整数数组 arr ,数组中的每个整数 互不相同 。另有一个由整数数组构成的数组 pieces,其中的整数也 互不相同 。请你以 任意顺序 连接 pieces 中的数组以形成 arr 。但是,不允许 对每个数组 pieces[i] 中的整数重新排序。

如果可以连接 pieces 中的数组形成 arr ,返回 true ;否则,返回 false 。

2. 思路分析

判断piece中所有切片拼起来是不是arr。
字典储存arr下标,遍历每个piece从字典里找第一个字符位置,然后从位置匹配
最坏时间复杂度O(n)
36 ms Python3 75.21%

3. 代码实现

class Solution:
    def canFormArray(self, arr: List[int], pieces: List[List[int]]) -> bool:
        s  = {v:k for k,v in enumerate(arr)}
        n = len(arr)
        for piece in pieces:
            i = s.get(piece[0])
            if i is None:
                return False
            for c in piece          :  
                if i == n or arr[i] != c:
                    return False
                i += 1            
        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值