第一题:189轮转数组
题目链接
解题思路
辅助空间
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k %= n
tmp = nums[n - k:].copy()
for i in range(n - k - 1, -1, -1):
nums[i + k] = nums[i]
for i in range(0,k):
nums[i] = tmp[i]
双指针+翻转数组法
思路
- 先整体翻转数组,即翻转【0,n-1】区间
- 然后分别饭庄【0,k-1】和【k,n-1】区间即为结果
def reverse(nums:List[int],left,right) ->None:
i,j = left,right
while i <j:
nums[i],nums[j] = nums[j],nums[i]
i += 1
j -= 1
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k %= n
reverse(nums,0,n-1)
reverse(nums,0,k-1)
reverse(nums,k,n-1)
第二题:238.除自身以外数组的乘积
题目链接
238. 除自身以外数组的乘积 - 力扣(LeetCode)
解题思路
前缀和
使用数组s1
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
s1, s2 = [1] * (n + 2), [1] * (n + 2)
for i in range(1, n + 1):
s1[i] = s1[i - 1] * nums[i - 1]
for i in range(n, 0, -1):
s2[i] = s2[i + 1] * nums[i - 1]
ans = [s1[i - 1] * s2[i + 1] for i in range(1, n + 1)]
return ans
和数组s2分别计算范围【1,x】的前缀和范围【x,n】的后缀乘法。
ans[i-1] = s1[i - 1] * s2[i + 1]
第三题:41.确实的第一个正数
题目链接
解题思路
首先,我们使用set(range(1, len(nums) + 2))创建一个集合,其中包含从1到数组长度加1的所有正整数。然后,我们使用set(nums)创建另一个集合,其中包含数组中的所有元素。
接下来,我们使用集合的差集操作set(range(1, len(nums) + 2)) - set(nums),得到一个集合,其中包含在第一个集合中但不在第二个集合中的元素。
最后,我们使用min()函数找到这个集合中的最小值,即为未出现的最小正整数。
这个解法的时间复杂度为O(n),其中n为数组的长度。同时,我们只使用了常数级别的额外空间,即两个集合的空间。
解题代码
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
return min(set(range(1, len(nums) + 2)) - set(nums))