### 题目描述 你和一群强盗准备打劫银行。给你一个下标从 0 开始的整数数组 security ,其中 security[i] 是第 i 天执勤警卫的数量。日子从 0 开始编号。同时给你一个整数 time 。 如果第 i 天满足以下所有条件,我们称它为一个适合打劫银行的日子: - 第 i 天前和后都分别至少有 time 天。 - 第 i 天前连续 time 天警卫数目都是非递增的。 - 第 i 天后连续 time 天警卫数目都是非递减的。 更正式的,第 i 天是一个合适打劫银行的日子当且仅当:security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time]. 请你返回一个数组,包含** 所有 **适合打劫银行的日子(下标从 0 开始)。返回的日子可以** 任意 **顺序排列。 ### 输入输出 #### 示例1 ``` 输入:security = [5,3,3,3,5,6,2], time = 2 输出:[2,3] 解释: 第 2 天,我们有 security[0] >= security[1] >= security[2] <= security[3] <= security[4] 。 第 3 天,我们有 security[1] >= security[2] >= security[3] <= security[4] <= security[5] 。 没有其他日子符合这个条件,所以日子 2 和 3 是适合打劫银行的日子 ``` ### 示例2 ``` 输入:security = [1,1,1,1,1], time = 0 输出:[0,1,2,3,4] 解释: 因为 time 等于 0 ,所以每一天都是适合打劫银行的日子,所以返回每一天。 ``` ### 示例3 ``` 输入:security = [1,2,3,4,5,6], time = 2 输出:[] 解释: 没有任何一天的前 2 天警卫数目是非递增的。 所以没有适合打劫银行的日子,返回空数组。 ``` ### 示例4 ``` 输入:security = [1], time = 5 输出:[] 解释: 没有日子前面和后面有 5 天时间。 所以没有适合打劫银行的日子,返回空数组。 ``` **提示** - 1 <= security.length <= 10^5 - 0 <= security[i], time <= 10^5 ### 题目解答 #### 思路分析 **方法1——朴素的查找方式** 遍历每天,向前向后遍历,查看其向前time是否满足非递增,其向后time是否满足非递减,如果满足的话将其加入结果。 **算法复杂度分析:** 设security天数为n, times的数值为m. 时间复杂度:最多有$$n-2m$$天满足, 每天需要向前看m个,向后看m个位置。因此时间复杂度$$2m(n-2m)$$ 空间复杂度:除了结果记录的$$n-2m$$位置,无需额外的空间资源。 **该方式的复杂度会超时** **方法2——记录数组的增减情况** 我们需要寻找先减后增这种情况\\\\\///,通过遍历数组,记录数组前后的增减情况。 对于以下数组,我们记录每个位置的数字**之前**可以形成多长的非递增序列。每个位置的数字**之后**可以形成多长的非递减序列。 Example [5,3,3,3,5,6,2] times=2 - 形成**非递增**数组从左到右遍历有:[1, 2,3,4,1,1,2] - 形成**非递减**数组2从右到左遍历有:[1,5,4,3,2,1,1] 对于times=2,需要找某个位置前的非递增数组大于time+1,即2个数组中均大于等于3的位置。可以看到只有位置2,3满足条件将其返回即可。 **算法复杂度分析:** 时间复杂度:遍历一共需要遍历3次数组,前两次生成递增递减数组,最后一次判断是否符合条件。时间复杂度$$O(3n)$$ 空间复杂度:需要额外的2个数组记录$$O(2n)$$ #### 代码实现 class Solution: # 每个处理左右会超时 def goodDaysToRobBank(self, security: List[int], time: int) -> List[int]: res = list() for i in range(time, len(security) - time): flag = True for j in range(i, i-time, -1): if security[j] > security[j-1]: flag = False break if not flag: continue for j in range(i, i+time): if security[j] > security[j+1]: flag = False break if flag: res.append(i) return res # 遍历数组的递增递减情况 def goodDaysToRobBank(self, security: List[int], time: int) -> List[int]: increase = [1] * len(security) decrease = [1] * len(security) # 从右到左遍历,获取数组右侧的非递减数组 for i in range(len(security)-1, 0, -1): if security[i-1] <= security[i]: increase[i-1] = increase[i] + 1 # 从左到右遍历,获取数组左侧的非递增数组 for i in range(1, len(security)): if security[i] <= security[i-1]: decrease[i] = decrease[i-1] + 1 res = list() for i in range(time, len(security) - time): if increase[i] >= time+1 and decrease[i] >= time+1: res.append(i) return res 最后编辑:2024年04月23日 ©著作权归作者所有 赞 0 分享
最新回复