LeetCode 977.有序数组的平方
题目链接
思路
第一反应 拿到每个元素分别平方一下,再做个弊(哦不是)再排个序
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
nums[i] = nums[i] ** 2
return sorted(nums)
来吧正常的算法流程:走下双指针 思路就是用两个指针指向两头,因为两头的元素一定是最大的,然后按照谁大谁先的原则从后向前塞进定义的新数组,就完事了
def sortedSquares(self, nums: List[int]) -> List[int]:
new = len(nums) - 1
new_list = []
left, right = 0, len(nums)-1
while left <= right:
if (nums[left] ** 2) > (nums[right] ** 2):
new_list[new] = nums[left] ** 2
left += 1
new -= 1
else:
new_list[new] = nums[right] ** 2
right -= 1
new -= 1
return new_list
这里会报“list assignment index out of range”是因为new_list是空的,不能从尾巴开始塞,所以只要不让新定义的数组是空的就行,我这里给他全写了0,就过了
new_list = [0 for i in range(len(nums))]
完整的代码
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
new = len(nums) - 1
new_list = [0 for i in range(len(nums))]
left, right = 0, len(nums)-1
while left <= right:
if (nums[left] ** 2) > (nums[right] ** 2):
new_list[new] = nums[left] ** 2
left += 1
new -= 1
else:
new_list[new] = nums[right] ** 2
right -= 1
new -= 1
return new_list
反思
如果卡哥不讲,我是万万想不到用双指针的思路的。写的时候还感觉小用到了一下左闭右闭的原则
LeetCode 209.长度最小的子数组
题目链接
思路
一开始是想做两个指针,一个是用来指开始计算的位置,一个负责加后面的数字,两个for循环暴力解,但是没写出来
(原来的)(没整出来)
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
min_length = len(nums)
for i in range(len(nums)):
length = 0
sum = nums[i]
while sum < target and ((i+1) < len(nums)):
length += 1
i += 1
sum += nums[i]
if min_length > (length + 1):
min_length = length + 1
return min_length
写出来了,但是超时(还是要再理一理…不对鸭感觉还是错的啊。。救命,谢谢了,我先用滑动窗口吧)
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
min_length = len(nums)
length = 0
sum = 0
for i in range(len(nums)):
sum = 0
j = i
sum = nums[i]
while j < len(nums):
if sum >= target:
length = j - i + 1
if min_length > length:
min_length = length
break
else:
sum += nums[i]
j += 1
return min_length
这道题用的思想是滑动窗口,相比暴力是两个for,这里用一个for循环就可以搞定,时间复杂度是O(n)。思想是:一个指针指向窗口尾巴,让窗口内sum保持大于target并不断缩减起始的位置,直到<target就开始移动尾指针,直到结束
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
sum, i = 0, 0
min_length = float("inf")
for j in range(len(nums)):
sum += nums[j]
while sum >= target:
min_length = min(min_length, j-i+1)
sum -= nums[i]
i += 1
return 0 if min_length == float("inf") else min_length
反思
暴力想法嵌套两个for循环,换成滑动窗口仅一个for循环即可完成。这道题做了很久,思路大差不差但是就是无法通过,python的语法感觉写起来也不太顺,还是要多练练
LeetCode 59.螺旋矩阵II
题目链接
思路
第一反应 一点思路都没有
解答思想:按照四条边来塞数字,4个For循环,转圈次数作为循环大条件,用一个变量调整边距。以及要考虑如果是奇数,额外处理最中间的位置值
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
nums = [[0]*n for _ in range(n)]
count = 1
loop = n//2
offset = 1
startx, starty = 0, 0
for offset in range(1, loop+1):
for j in range(starty, n-offset):
nums[startx][j] = count
count += 1
for i in range(startx, n-offset):
nums[i][n-offset] = count
count += 1
for j in range(n-offset, starty, -1):
nums[n-offset][j] = count
count += 1
for i in range(n-offset, startx, -1):
nums[i][starty] = count
count += 1
startx += 1
starty += 1
if n%2 == 1:
nums[n//2][n//2] = count
return nums
反思
这题确实体现出了coding能力很薄弱,拿到题的时候思维很混乱,不知道怎么写对,只能套判断套判断套for,整不出来,从四条边的角度和对转圈的考虑确实给我很大帮助。勤能补拙吧
还漏了一个很重要的点,循环不变量原则,这道题的循环不变量处理,是对于每一圈四条边的处理,操作都是一样的,并且都实行左闭右开原则,这样不会乱也能保证代码简洁
数组总结
· 循环不变量:找到问题的突破口的方式之一,解决包括代码冗余的情况
· 二分法:对于有序的数组,进行查找非常便捷
· 滑动窗口:通过控制起始位置,控制窗口内的情况从而做出判断
` 双指针:用一个for解决两个for的问题很有帮助