代码随想录算法训练营第二天|209长度最小的子数组、59螺旋矩阵
1 leetcode209长度最小的子数组
题目链接:209. 长度最小的子数组
文章链接:代码随想录 (programmercarl.com)
视频链接:拿下滑动窗口! | LeetCode 209 长度最小的子数组
思路:没有思路,看到这道题有一种想立马退出的感觉,无从下手
1.1暴力搜索
1.1.1python版本
这个版本的新知识就是定义一个无限大的数使用的是num = float('inf')
- 两层for循环
这个代码可以运行,但是在这个列表太长的情况下出现了一个超出索引
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
result = float('inf')
for i in range(len(nums)):
sum_num = 0
for j in range(i,len(nums)):
sum_num +=nums[j]
if sum_num>=target:
middle = j-i+1
result = min(result,middle)
break
return result if result !=float('inf') else 0
- 两层循环用while
暴力搜索还是超出时间限制了
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
result = float('inf')
i = 0
while i<len(nums):
sum_num = 0
j = i
while j <len(nums):
sum_num +=nums[j]
if sum_num>=target:
middle = j-i+1
result = min(result,middle)
break
j +=1
i +=1
return result if result !=float('inf') else 0
1.1.2 C++版本
- 定义一个无限大的数是```num = INT32_MAX``
- 语法
if a<b: a=a else:a=b
在 这个语言中可以写成a=a<b?a:b
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
for (int i =0;i<nums.size();i++){
int sum_num = 0;
for(int j=i;j<nums.size();j++){
sum_num = sum_num+nums[j];
if (sum_num>=target){
result = result<(j-i+1)?result:(j-i+1);
break;
}
}
}
return result == INT32_MAX ? 0 : result;
}
};
1.2滑动窗口的思路
这个里面的一个思路两个指针滑动首先滑动的是终止位置的,第二个里面使用if还是while的判断,才开始不理解,后面举个例子而言target = 7,nums=[3,1,2,4]
,如果是if的话就i继续增加,他的长度不会改变,但是使用while循环的话,终点的指针保持不变,对n进行增加的话,nums=[1,2,4]
也同样满足要求
1.2.1 python版本
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = 0
sum_num = 0
result = float('inf')
for i in range(len(nums)):
sum_num +=nums[i]
while sum_num>=target:
sublength = i-n+1
result = min(result,sublength)
sum_num -=nums[n]
n +=1
return result if result != float('inf') else 0
1.2.2 C++版本
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum_num = 0,start_ind = 0;
for (int i=0;i<nums.size();i++){
sum_num +=nums[i];
while (sum_num>=target){
int sublength = i-start_ind+1;
result = result <sublength?result:sublength;
sum_num -=nums[start_ind];
start_ind++;
}
}
return result ==INT32_MAX ?0:result;
}
};
1.3滑动窗口小结
- 针对滑动窗口首先要知道循环中改变的是什么数值,是终止位置的索引位置
- 为什么判断大小的时候用的是while循环而不是if条件判断,因为这道题需要找的是最小索引值,最简单的例子,数组循环遍历的时候,
target = 7,nums=[3,1,2,4]
,如果使用条件语句的话直接返回的值是4,但是根据我们题目要求要找到最小值,1+2+4=7,这个的长度为3,比4小,所以要用while循环,而不是if条件判断
2 leetcode59 螺旋矩阵II
题目链接:59. 螺旋矩阵 II - 力扣(LeetCode)
文章链接:代码随想录 (programmercarl.com)
视频链接:手把手带你学会操作链表 | LeetCode:203.移除链表元素
思路:看完视频做的时候还会很懵的一道题,哈哈哈哈哈
2.1算法解决问题结果
2.1.1 python版本
这里定义一个二维n*n全为0的列表方法new_list = [[0]*n for _ in range(n)]
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
l = 0
startx,starty = 0,0
count = 1
new_list = [[0]*n for _ in range(n)]
offset = 1
mid = n//2
while l<mid:
i,j =startx,starty
while j<(n-offset):
new_list[startx][j] = count
count +=1
j +=1
while i<(n-offset):
new_list[i][j] = count
count +=1
i +=1
while j>starty:
new_list[i][j] =count
count+=1
j -=1
while i>startx:
new_list[i][j] = count
count +=1
i -=1
startx +=1
starty +=1
offset +=1
l +=1
if n%2 !=0:
new_list[mid][mid] = count
return new_list
2.2.2 C++版本
C++里面定义一个矩阵的方法就是两层数组,即vector<vector<int>> res(n,vector<int>(n,0));
这句话开始vector<vector<int>>
是定义数组的类型,就是二维数组
res
表示的数组的名称
(n,vector<int>(n,0))
这句话里面首先是代表数组的列有n列,然后再一个向量中嵌套一个向量即为矩阵,第二个就是给定行以及内部的赋值
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));
int startx=0,starty=0;
int for_num = n/2,mid = n/2;
int offset =1,count = 1;
int i,j;
while (for_num--){
i = startx;
j = starty;
for (j;j<n-offset;j++){
res[startx][j] = count++;
}
for (i;i<n-offset;i++){
res[i][j]=count++;
}
for (j;j>starty;j--){
res[i][j]=count++;
}
for (i;i>startx;i--){
res[i][j]=count++;
}
offset++;
startx++;
starty++;
}
if (n%2){
res[mid][mid]=count;
}
return res;
}
};
2.2 螺旋矩阵总结
- 定义矩阵的方法是要在一个一维列表的基础上在里面进行嵌套,对其行进行确定即可定义
- 这里的代码写法有一点需要注意,其内部的循环是模拟人行走的过程,所以代码的行和列顺着旋转即可
- 代码旋转完以后如果是奇数则需要确定中间数值,否则就是可以跳出矩阵
3 leetcode54 螺旋矩阵
3.1 算法解决问题及结果
3.1.1 python版本
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
m,n =len(matrix),len(matrix[0])
loop = min(m,n)//2
startx,starty = 0,0
l = []
offset = 1
middle = min(m,n)//2
while loop:
i ,j= startx,starty
while j<n-offset:
l.append(matrix[startx][j])
j +=1
while i <m-offset:
l.append(matrix[i][j])
i+=1
while j>starty:
l.append(matrix[i][j])
j -=1
while i >startx:
l.append(matrix[i][j])
i -=1
startx +=1
starty +=1
loop -=1
offset +=1
if min(m,n)%2 !=0:
if m<n:
for k in range(middle,n-middle):
l.append(matrix[middle][k])
elif m>n:
for a in range(middle,m-middle):
l.append(matrix[a][middle])
else:
l.append(matrix[middle][middle])
return l
4 今日总结
4.1代码部分
4.1.1 python
- 在定义一个数字无限大的时候,使用的方法是将其数值定义为
float('inf')
- 定义一个n*n矩阵内部全为0的矩阵方法是
l = [[0]*n for _ in range(n) ]
4.1.2 C++部分
- 定义一个无限大的数字代码为
INT32_MAX
- 比较一个数值是用其原始值还是使用新计算的值的代码为
a = a<b ? a:b
- 定义一个n*n的矩阵的代码是
vector<vector<int>> res (n,vector<int>(n,0))
4.2 题目部分
- 最小长度的思路就是滑窗,滑窗的关键要知道外层循环中的快速数值是什么,主要为终止位置的后缀,慢指针为起始位置的地方
- 螺旋矩阵转动的题目,主要看的点在于其旋转过程中对于矩形而言,其每条边应该选择左闭又开区间的代码对其进行循环