LeetCode:数组(二)
本组囊括数组相关题目,难度不等:
35.Search Insert Position
题目描述:简单
这是一个简单的二分查找问题,只不过最后寻找完后未找到就返回Low而不是None,这里即可返回目标值应插入位置,注意:这里的重点在于二分法的边界条件不要弄错,记住这个模板。
1 class Solution: 2 def searchInsert(self, nums: List[int], target: int) -> int: 3 low = 0 4 high = len(nums) - 1 5 while low <= high: 6 mid = (high + low) // 2 7 guess = nums[mid] 8 9 if guess == target: 10 return mid 11 elif guess > target: 12 high = mid - 1 13 else: 14 low = mid + 1 15 return low 16 # 二分查找的模板,要记住边界条件
41.First Missing Positive
题目描述:困难
提示:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。
如果没有这条提示,其实最暴力解法是先做快速排序,再做二分查找,但这样时间复杂度太高了。
解法一:
## 官方正解:将数组视为哈希表,自己重写编写哈希函数的规则
## 就这个题目来说,规则即把数组中值为i的数映射到下标i-1去,如把数字1放到a[0]:
1 class Solution: 2 def firstMissingPositive(self, nums: List[int]) -> int: 3 # 自己想到的是先做快速排序,再做二分查找,这样不符合时间复杂度 4 ## 正解:讲数组视为哈希表,自己重写编写哈希函数的规则 5 ## 就这个题目来说,规则即把数组中值为i的数映射到下标i-1去,如把数字1放到a[o]: 6 size = len(nums) 7 for i in range(size): 8 # 首先判断这个i是新数组的索引对应的值, 不满足条件就交换 9 while 1 <= nums[i] <= len(nums) and nums[i] != nums[nums[i]-1]: 10 self.__swap(nums, i, nums[i]-1) 11 12 for i in range(size): 13 if i+1 != nums[i]: 14 return i+1 # 这里遍历一遍新数组,如果当前下标对应的值不是下标+1的话,就返回下标+1即为答案 15 return size+1 # 遍历完仍没出现上述情况,则整个新数组长度+1即为正确答案 16 # 这里记住一点,次要逻辑都可以重新写一个函数,这样可以避免出错 17 def __swap(self, nums, index1, index2): 18 nums[index1], nums[index2] = nums[index2], nums[index1]
53.Maximum Subarray
题目描述:简单
这道题求的是最大子序和,通常解法是由动态规划的思路求解,但题目中进阶所说的使用分治法求解较为困难,这里先不使用。
回到动态规划:我们可以考虑设置一个sum为数组前几项的和,如果这个和为正,则它对下一个数字有增益,则sum+=当前数字;如果这个和为负,则没有增益,最大和就直接从当前数字开始。遍历数组即可得到最大子序列和。此外,还要用一个ans来保存历史最大子序和的值。
1 class Solution: 2 def maxSubArray(self, nums: List[int]) -> int: 3 # 参考解法,动态规划 4 sum = 0 5 ans = nums[0] 6 for i in range(len(nums)): 7 if sum > 0: 8 sum += nums[i] 9 else: 10 sum = nums[i] 11 12 ans = max(ans, sum) 13 return ans 14 # 时间复杂度 O(n) 15 # 空间复杂度 O(1)