学习笔记@代码随想录day2:有序数组的平方 ,长度最小的子数组,螺旋矩阵
有序数组的平方
学习前写的暴力算法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
#自己的方法,先计算后排序
for i in range(len(nums)):
nums[i]=nums[i]*nums[i]
for i in range(len(nums)):
for j in range(len(nums)):
if nums[i]<nums[j]:
m=nums[i]
nums[i]=nums[j]
nums[j]=m
return nums
太过暴力导致在力扣上长输入超时/(ㄒoㄒ)/~~
调用python排序方法sort解决排序问题
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
# #自己的方法,先计算后排序
# for i in range(len(nums)):
# nums[i]=nums[i]*nums[i]
# for i in range(len(nums)):
# for j in range(len(nums)):
# if nums[i]<nums[j]:
# m=nums[i]
# nums[i]=nums[j]
# nums[j]=m
# return nums
for i in range(len(nums)):
nums[i]=nums[i]*nums[i]
#print(nums)
nums.sort()
return nums
扩展学习:
1.sorted() 函数可以对任何可迭代对象进行排序,包括列表、元组和字符串等。该函数会返回一个新的有序列表,原始列表不会被修改。
2.sort() 方法是列表对象的一个方法,可以对列表进行原地排序。即原始列表会被修改,而不是返回一个新的列表。
要指定降序排序,可以在 sorted() 函数或 sort() 方法中传递一个 reverse=True 参数。
这种方法的时间复杂度是这个时间复杂度是 O(n + nlogn), 可以说是O(nlogn)的时间复杂度。
下面用双指针思想来解决这个问题:
首先,排序的数组是有序数组,所以最大值从数组两边产生,所以考虑用双指针来解决这个问题。
下边是我看了视频和文档讲解后自己写的双指针法:
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
#双指针法
new_nums=[None]*len(nums)
i=0
j=len(nums)-1
k=len(nums)-1
while i<=j:
#最大的数值在数组两边产生
if nums[i]* nums[i]>nums[j]* nums[j]:
#如果最大值在左边,新数组中的最大值就等于左边的值
new_nums[k]=nums[i]* nums[i]
k-=1
#比较剩下的数组,此时左边的少一位,所以i+1
i+=1
else:
#此时最大值在右边,右边的数少一位,j-1
new_nums[k]=nums[j]* nums[j]
k-=1
j=j-1
return new_nums
代码随想录的双指针法
(版本一)双指针法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
l, r, i = 0, len(nums)-1, len(nums)-1
res = [float('inf')] * len(nums) # 需要提前定义列表,存放结果
while l <= r:
if nums[l] ** 2 < nums[r] ** 2: # 左右边界进行对比,找出最大值
res[i] = nums[r] ** 2
r -= 1 # 右指针往左移动
else:
res[i] = nums[l] ** 2
l += 1 # 左指针往右移动
i -= 1 # 存放结果的指针需要往前平移一位
return res
总结: 掌握了双指针算法的思想,但是一些基础需要多加巩固。
拓展: python里求平方用两个*号或pow(x,2),求开方用 math.sqrt()。
长度最小的子数组
力扣209:
'''
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组
[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
'''
这个题尝试自己写时,第一直觉就是先把连续的数组分离出来,再求和与target作比较。
遇到的第一个问题是:怎么把有序数组分离出来成为子数组?
本来想着先判断连续再来想下一步,但是判断连续就卡住了,写不出来/(ㄒoㄒ)/~~
看了讲解,再看来下题目,原来是我理解错了,连续子数组指的是数组连续,而不是数组的值连续/(ㄒoㄒ)/~~
看了讲解后自己写的代码
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
i=0#起始位置
sum_list=0#用于求子数组的和
min_s=10^9#假设初始的子数组长度为这么大
#滑动窗口思想,用双指针来遍历数组,一个遍历数组的起始位置,一个遍历数组的终止位置
for j in range(len(nums)):
#j表示终止位置
sum_list+=nums[j]
#print(sum_list)
while sum_list>=target:
subl=j-i+1
#当和大于目标值的时候,求子数组的长度并和当前最小的子数组比较,选择最小的子数组
min_s=min(min_s,subl)
sum_list=sum_list-nums[i]#此时已经达到条件,要开始查找下一个子数组,初值指针移动一位,所以要减去前一个值
i=+1
return min_s
出现问题:在本地运行结果是2,但在力扣上结果出错,我不理解!!!!(todo:明天来查找问题)
随想录给的代码
(版本一)滑动窗口法
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
l = len(nums)
left = 0
right = 0
min_len = float('inf')
cur_sum = 0 #当前的累加值
while right < l:
cur_sum += nums[right]
while cur_sum >= s: # 当前累加值大于目标值
min_len = min(min_len, right - left + 1)
cur_sum -= nums[left]
left += 1
right += 1
return min_len if min_len != float('inf') else 0
总结 思想掌握了,但是代码写得好像不够对,明天再过一遍!
螺旋矩阵
没有时间自己写代码了,先过下螺旋矩阵的思想:
看成很多正方形,按上下左右边的顺序来填数,遵循左闭右开原则,把每条边的最后一个节点留给下一条边处理。
主要代码思想:
1.判定迭代次数,n//2,暂时是按照3的时候迭代一次,4迭代两次,5两次,6三次
2.奇数时中间填最后一个数n^2
3.4层循坏,表示4条边,四条边循坏结束后,要更新迭代次数,更新下一个开始的小正方形左上的位置坐标。
明日补上自己写的代码!
总结
今天的题比昨天难度大,主要没有预留好时间,暂时先掌握了基本算法思想,明天或者后天把代码补上,加油!
参考链接:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html#%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3