上题
第一题
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例1
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例2
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
第一眼,一个sort()函数搞定。。。。时间复杂度n*log2^n,不满足要求
def sortedSquares(self, nums):
"""
第一遍,凭第一感觉解
"""
for i in range(len(nums)):
nums[i] = nums[i]**2
nums.sort()
return nums
思路
- 正数序列平方最大值在最右边,负数序列最大值平方在最左边,双指针指向头尾,分别比较最大值,较大值加入目标数组队尾,同时移动较大值指针继续比较
-
先找到负值和正值的分界点, 相当于找到了平方后的最小值, 然后向两边不断进行遍历
def sortedSquares1(self, nums):
"""
定睛一看,时间复杂度不满足要求。
看思路:
1.双指针
2.先找到负值和正值的分界点, 相当于找到了平方后的最小值, 然后向两边不断进行遍历,多找分界点多用了一层循环
"""
result = [0]*len(nums)
fir, end, size = 0, len(nums) - 1, len(nums) - 1
while fir <= end:
if nums[fir]**2 > nums[end]**2:
result[size] = nums[fir]**2
fir += 1
else:
result[size] = nums[end] ** 2
end -= 1
size -= 1
return result
代码
class Solution:
"""
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
"""
def sortedSquares(self, nums):
"""
第一遍,凭第一感觉解
"""
for i in range(len(nums)):
nums[i] = nums[i]**2
nums.sort()
return nums
def sortedSquares1(self, nums):
"""
定睛一看,时间复杂度不满足要求。
看思路:
1.双指针
2.先找到负值和正值的分界点, 相当于找到了平方后的最小值, 然后向两边不断进行遍历,多找分界点多用了一层循环
"""
result = [0]*len(nums)
fir, end, size = 0, len(nums) - 1, len(nums) - 1
while fir <= end:
if nums[fir]**2 > nums[end]**2:
result[size] = nums[fir]**2
fir += 1
else:
result[size] = nums[end] ** 2
end -= 1
size -= 1
return result
if __name__ == '__main__':
test = Solution()
nums = [[-4, -1, 0, 3, 10], [-7, -3, 2, 3, 11]]
for tem in nums:
print(test.sortedSquares1(tem))
想不到第一种方法反而更好些。。。。
第二题
给定一个含有 n 个正整数的数组和一个正整数 target,找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例1
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例2
输入:target = 4, nums = [1,4,4]
输出:1
示例3
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
思路
- 变长滑动窗口,累加和 sum<target时,右指针右滑,逐个加入新元素并累加计算
- 当累加和sum>target时,计算窗口长度,左指针右移,剔除窗口最左边元素,重复第一步,开始计算新窗口
- 循环条件取left<len(nums),因为当right=len(nums)时,若sum>target,left右移仍可能存在其它满足条件的解
- 若right移到最右边时sum<target,结束查找,因为没有新元素加入,sum无法在增大
- right指向右窗口的下一位,那 right-left刚好为窗口长度
代码
class Solution:
"""
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
"""
def minSubArrayLen(self, target, nums):
"""
滑动窗口:定长和可变长两类,本题使用可变长
"""
left, right = 0, 0
minlen = len(nums) + 1
list_sum = 0
while left < len(nums):
if list_sum < target:
# 这个判断放在外层不管是开头还是结尾都会导致少算一次,left +1 == len(nums)后,还需进入下一次循环做一次入队后的大小判断
if right == len(nums):
break
list_sum += nums[right]
right += 1
else:
# 满足条件更新最小值
minlen = min(minlen, right-left)
# 剔除最左边元素
list_sum -= nums[left]
left += 1
return minlen if minlen < len(nums) + 1 else 0
if __name__ == '__main__':
test = Solution()
nums = [[2, 3, 1, 2, 4, 3], [1, 4, 4], [1, 1, 1, 1, 1, 1, 1, 1]]
target = [7, 4, 11]
for i in range(len(nums)):
print(test.minSubArrayLen(target[i], nums[i]))
第三题
思路
就像是重回到高中做不出最后一道数学大题的迷茫和无助。。。。第一遍反复看别人的思路,每次循环结束记得更新边界值
代码
class Solution:
"""
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
"""
def minSubArrayLen(self, target, nums):
"""
滑动窗口:定长和可变长两类,本题使用可变长
"""
left, right = 0, 0
minlen = len(nums) + 1
list_sum = 0
while left < len(nums):
if list_sum < target:
# 这个判断放在外层不管是开头还是结尾都会导致少算一次,left +1 == len(nums)后,还需进入下一次循环做一次入队后的大小判断
if right == len(nums):
break
list_sum += nums[right]
right += 1
else:
# 满足条件更新最小值
minlen = min(minlen, right-left)
# 剔除最左边元素
list_sum -= nums[left]
left += 1
return minlen if minlen < len(nums) + 1 else 0
if __name__ == '__main__':
test = Solution()
nums = [[2, 3, 1, 2, 4, 3], [1, 4, 4], [1, 1, 1, 1, 1, 1, 1, 1]]
target = [7, 4, 11]
for i in range(len(nums)):
print(test.minSubArrayLen(target[i], nums[i]))
总结
只有十分努力,才能看起来毫不费力。。。。我现在就很费力