1.学习
2.数组
2.1第53题-最大子数组和
给你一个整数数组 nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
心得:一直在纠结这个连续的事情,最后发现根本没必要管,因为如果前一个数与当前数相加小于当前数,前面的部分就会直接被舍弃,如果相加大于当前数则会一直叠加。
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = copy.deepcopy(nums)
max_ = dp[0]
for i in range(1,len(nums)):
dp[i] = max(dp[i-1]+nums[i], dp[i])
if max_ < dp[i]:
max_ = dp[i]
return max_
时间和内存占用太多,根本没必要再生成一个dp数组,直接用nums数组更新就行。
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# dp = copy.deepcopy(nums)
max_ = nums[0]
for i in range(1,len(nums)):
nums[i] = max(nums[i-1]+nums[i], nums[i])
if max_ < nums[i]:
max_ = nums[i]
return max_
2.2第56题-合并区间
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]] 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
class Solution(object):
def merge(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: List[List[int]]
"""
new_int = []
a = []
intervals.sort()
for i in range(1,len(intervals)):
# 前一个end大于后一个start
if intervals[i-1][1] > intervals[i][0]:
# 前一个end小于后一个end
if intervals[i-1][1] <= intervals[i][1]:
intervals[i] = [intervals[i-1][0], intervals[i][1]]
else:
intervals[i] = intervals[i-1]
elif intervals[i-1][1] == intervals[i][0]:
intervals[i] = [intervals[i-1][0], intervals[i][1]]
else:
new_int.append(intervals[i-1])
new_int.append(intervals[-1])
return new_int
2.3第189题-轮转数组
给定一个整数数组 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]
class Solution(object):
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
# if k == 0:
# return nums
nums1 = copy.deepcopy(nums)
k = k % len(nums)
start = len(nums)-k
# nums2 = []
# nums1 = nums[:start]
# nums2 = nums[start:]
for i in range(len(nums)):
if i < k:
nums[i] = nums[start+i]
else:
nums[i] = nums1[i-k]
感觉不用深拷贝整个数组
class Solution(object):
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
k = k % len(nums)
start = len(nums)-k
nums1 = nums[:start]
nums2 = nums[start:]
for i in range(len(nums2)):
nums[i] = nums2[i]
for j in range(len(nums1)):
nums[j+k] = nums1[j]
看了答案,发现我最早想出的方法就是最简单的答案,nums[:]=nums[start:]+nums[:start],但是发现一直不能修改nums的值,看了答案发现nums忘记加[:]了,吐了。
class Solution(object):
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
k = k % len(nums)
start = len(nums)-k
nums[:] = nums[start:] + nums[:start]
2.4除自身以外数组的乘积
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请不要使用除法,且在 O(n)
时间复杂度内完成此题。
示例 1:
输入: nums =[1,2,3,4]
输出:[24,12,8,6]
先用最简单的遍历法,果然超时。
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
len_ = len(nums)
answer = [1]*len_
for i in range(len_):
for j in range(len_):
if j != i:
answer[i] = answer[i]*nums[j]
return answer
然后把数组分为i点的前半部分和后半部分相乘来计算,这样的话减少很多重复计算的时间。
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
# 可以把乘积分为前半部分和后半部分
len_ = len(nums)
answer = [1]*len_
forward = [1]*len_
back = [1]*len_
for i in range(1,len_):
forward[i] = forward[i-1]*nums[i-1]
for j in reversed(range(len_-1)):
back[j] = back[j+1]*nums[j+1]
for k in range(len_):
answer[k] = forward[k]*back[k]
return answer
看了答案,知道了左边的乘积其实可以动态的变化
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
# 可以把乘积分为前半部分和后半部分
len_ = len(nums)
answer = [1]*len_
back = 1
for i in range(1,len_):
answer[i] = answer[i-1]*nums[i-1]
for j in reversed(range(len_)):
answer[j] = answer[j]*back
back = back * nums[j]
return answer
2.5第41题-缺失的第一个正数
给你一个未排序的整数数组 nums
,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n)
并且只使用常数级别额外空间的解决方案。
示例 1:
输入:nums = [1,2,0] 输出:3
用最朴素的方法来寻找,不出所料,超时。
class Solution(object):
def firstMissingPositive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in range(len(nums)-1):
j = 0
while j < len(nums)-1-i:
if nums[j] > nums[j+1]:
temp = nums[j]
nums[j] = nums[j+1]
nums[j+1] = temp
j = j + 1
# print(nums)
if nums[-1] <= 0:
return 1
index_1 = 0
for j in range(len(nums)):
if nums[j] > 0:
if nums[j] != 1:
return 1
else:
index_1 = j
break
a = 1
# print(index_1)
for k in range(index_1+1,len(nums)):
a = a + 1
if nums[k] == a:
continue
elif nums[k] == a-1:
a = a - 1
continue
else:
return a
return a + 1
看了解析,知道当nums长度为N时,正数的数目肯定在[1,N]范围内,这时候就可以用哈希表来查找,内存占用多但速度快。把nums中的数都放在哈希表中,然后遍历[1,N],如果有哈希表中不存在则返回i,若都存在则返回i+1。
class Solution(object):
def firstMissingPositive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
hash_table = set(nums)
n = len(nums)
a = 0
for i in range(1,n+1):
if i in hash_table:
a = i
continue
else:
return i
return a + 1