1.最大子数组和
-
题目描述
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。 -
解题思路
动态规划,遍历数组求取以当前元素为结尾的子数组的和,如果前面的和大于0,那么加上当前元素,如果前面的和小于0,则从当前元素重新开始计算
时间复杂度:O(n) 空间复杂度:O(1) -
代码
pythonclass Solution: def maxSubArray(self, nums: List[int]) -> int: n = len(nums) if n == 0: return None res = nums[0] prev = nums[0] for i in range(1, n): cur = nums[i] if prev > 0: cur += prev res = max(res, cur) prev = cur return res
2. 合并区间
-
题目描述
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 -
解题思路
按照起始坐标排序,然后从前到后合并 -
代码
pythonclass Solution: def merge(self, intervals: List[List[int]]) -> List[List[int]]: n = len(intervals) if n < 2: return intervals intervals = sorted(intervals, key=lambda x: x[0]) res = [] prev = intervals[0] for i in range(1, n): cur = intervals[i] if cur[0] <= prev[1]: prev[1] = max(cur[1], prev[1]) else: res.append(prev) prev = cur res.append(prev) return res
3. 轮转数组
-
题目描述
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4]
-
解题思路
先翻转整个数组,再分别翻转两个局部数组;
注意k的大小可能会大于n,因此需要取余
时间复杂度:O(n) 空间复杂度:O(1)
-
代码
pythonclass Solution: def rotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ def reverse(nums, l, r): i = l j = r while i < j: nums[i], nums[j] = nums[j], nums[i] i += 1 j -= 1 n = len(nums) # 注意k有可能会大于n,因此需要对n取余数 k = k % n reverse(nums, 0, n - 1) reverse(nums, 0, k - 1) reverse(nums, k, n - 1)
4. 除自身以外数组的乘积
-
题目描述
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n) 时间复杂度内完成此题。
-
解题思路
很容易可以想到,结果是 前缀乘积 * 后缀乘积,题目要求O(1)空间复杂度,且返回的结果res不算在空间复杂度内,那么就是用res保存前缀乘积,第二遍循环再依次乘以后缀乘积
时间复杂度:O(n) 空间复杂度:O(1)
-
代码
pythonclass Solution: def productExceptSelf(self, nums: List[int]) -> List[int]: n = len(nums) res = [1] * n for i in range(1, n): res[i] = res[i-1] * nums[i-1] post = 1 for i in range(n - 2, -1, -1): post *= nums[i+1] res[i] *= post return res
5. 缺失的第一个正数
-
题目描述
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 -
解题思路
原地哈希:我们可以使用原地哈希的方法,因为我们要查找的元素的范围是[1, n], 数组的下标是[0, n-1],因此我们可以将元素i放到下标i-1的位置上,将所有正数都放到对应的位置之后,从头到尾遍历一遍数组,如果nums[i] != i + 1,说明i + 1就是缺失的第一个正数。
时间复杂度:O(n) 空间复杂度:O(1) -
代码
pythonclass Solution: def firstMissingPositive(self, nums) -> int: n = len(nums) i = 0 # 不断将i的元素放到正确的位置 while i < n: # 如果当前元素不在[1, n]的范围内,或者当前元素已经和目标位置的元素相等,那么直接跳过 if nums[i] <= 0 or nums[i] > n or nums[nums[i] - 1] == nums[i]: i += 1 continue cur = nums[i] # 将nums[i]放到nums[i]-1的位置上 nums[i], nums[cur-1] = nums[cur-1], nums[i] for i in range(n): if nums[i] != i + 1: return i + 1 # 注意,如果[1, n]的所有元素都在数组内,缺失的第一个正数就是n+1,因此返回n+1 return n + 1