977有序数组的平方
力扣
思路:
第一:
和之前一样的,看见数组我们的第一想法就是使用双指针去解。这道题需要额外开辟一个答案数组去储存结果。
第二:
头指针指向第一个元素,尾指针指向最后一个元素。然后对两个元素分别进行平方。这里看清题目意思:最终的数组依然是一个有序数组。也就是说是按照从小到大的顺序去排列。那么我们肯定是首先取平方大的那个元素放入我们的答案数组中去。
也就是说
if (left)**2 > (right)**2,那么(left)**2这个就要储存到数组中去。这里还有一个点要注意。就是我们答案数组的创建。不能直接创造一个空数组[],而是用[-1]*len(nums)。根据题目数组的长度去创建一个同样长度的数组。因为我们需要之后的尾部指针和头部指针需要不断的移动。如果是一个空数组,那么只能做到一个不断被赋值而不是起到一个储存的作用了。
代码:
def sortedSquares(self, nums: List[int]) -> List[int]:
result = [-1]*len(nums)
k = len(nums)-1
i = 0
j = len(nums)-1
while i <=j:
if nums[i]**2 > nums[j]**2:
result[k] = nums[i]**2
i+=1
else:
result[k] = nums[j]**2
j-=1
k-=1
return result
这里的k代表答案数组中的指针,需要不断的更新替换来达到一个储存的作用。
209 长度最小子数组
力扣
思路:
第一:
这道题目难点在于如何确定起始位置和终止位置。这里用i和j分别代表起点和终点。
很明显,这道题用i代表起点位置,j代表终点位置。
第二 :
首先创建一个sum = 0,然后循环的加上nums[j],一旦发现这个sum>=target了之后,说明找到了满足提议的元素,然后这里用当前j的下标-i的下标+1(因为下标从0开始)得到当前数组的长度。然后更新我们的result(这里result初始化为一个最大值max)在这里不断更新result来储存我们满足题意的元素和的长度。也就是储存有几个元素的和(并且长度是最小的)满足大于等于target。那下一次的循环,我们的起点位置也要更新,并且当前的sum要减去nums[i],也就是起点元素变化了,有新的了。然后i+=1。
最后我们检查的时候,这里有一个特殊情况,如果给定的数组是[1,1,1,1,1],target = 7.那么他其实全部加起来也不可能满足我们的要求,也就是说我们的result根本不会被更新,因为进入不到我们的循环中去。所以最后我们检查的时候应该是 return 0 if result==float('inf) else result
如果还是等于初始的最大值说明这个无解,那么就返回0 ,不然就返回我们的答案。
代码:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
i = 0
sum_j = 0
result = float('inf')
for j in range(len(nums)):
sum_j +=nums[j]
while sum_j>=target:
sub_l = j-i+1
result = min(result,sub_l)
sum_j-=nums[i]
i+=1
return 0 if result==float("inf") else result
这里 为什么是while sum_j>=target而不用if呢?这也就是我们刚才那个特殊情况,比如说数组是[1,1,1,1,100],target=100。当加到最后一个100的时候,我们满足了条件。如果这里用if的话,那么我们会用j当下的下标4,减去第一个元素的下标0然后+1,得到一个5的长度。然后if判断完成,这里我们最开始的for循环j也走到了最后,直接就退出了一整个大循环,那么我们最后的答案就是[1,1,1,100].但是这是我们想要的最短的答案长度吗?很明显这个不是,所以我们用while的原因就是,要让他一直减下去。直到得到一个最短的长度为止。
59螺旋矩阵
力扣
这道题 可谓是 梦魇般的存在 真的 四个循环 各位小伙伴真的真的要画图 这道题才能做 空想是很容易晕的。。。
思路:
第一:
首先 这道题给了一个数字n,会生成一个n*n的矩阵。那么首先我们就要根据这个去创建一个n*n矩阵。 其次!由于这个n的奇偶性质会影响循环的圈数。打个比方,如果是n=2,那就是一个2*2矩阵,那么转一圈就够了。如果n是3,那就是一个3*3矩阵。是不是就转不完,因为中间还剩一个数。所以首先有一个loop=n//2的圈数。
第二:
这道题分为四个边 从左到右 从上到下 从右到左 从下到上。 那么每一条边该遵循怎么样的规则去填充数字呢?这里建议大家统一遵守一个规则 左闭右开或者左闭右闭二选一。不要混淆着用,会直接晕掉的。。。。
第三:这里建议大家画一个n*n的矩阵图,然后标上坐标
以上图为例子。这里在设置一个start_x和start_y来控制我们每次当前需要填充的地方。
代码:
def generateMatrix(self, n: int) -> List[List[int]]:
#分为四个循环
#从左往右 从上到下 从右往左 从下到上
#先确定循环要几圈(根据n的奇偶性判断
#如果n=4,那就是一个4*4矩阵 那就是需要转4//2圈
#如果n=3,那就是一个3*3矩阵,那就需要3//2圈,然后剩下中间一个空
loop = n//2
#计数填充数字
count = 1
mid = n//2
#构造n*n矩阵
matrix = [ [0] * n for _ in range(n)]
#设置每条边的起点和终点 并且只遵循一种原则(左闭右开/左闭右闭)
start_x= 0
start_y = 0
#这里遵循左闭右开原则
for i in range(1,loop+1):
#先填充从左到右
for j in range(start_x,n-i):
matrix[start_x][j] = count
count+=1
#再填充 从上到下
for j in range(start_x,n-i):
matrix[j][n-i] = count
count+=1
#从右往左
for j in range(n-i,start_y,-1):
matrix[n-i][j] = count
count+=1
#从上往下
for j in range(n-i,start_y,-1):
matrix[j][start_y] = count
count+=1
start_x+=1
start_y+=1
if n%2!=0:
matrix[mid][mid] = n**2
return matrix
其实可以发现,如果n是奇数,那么剩下的那个数字其实就是n的平方。最后的if判断是根据n的奇偶性来检查是否需要补充数字,如果不需要的话就刚好直接返回我们新的matrix就可以了