209.长度最小的子数组
题目链接:209. 长度最小的子数组 - 力扣(LeetCode)
讲解链接:代码随想录
视频链接:
问题所在:没有梳理清楚整个代码逻辑,虽然理解题意,要素都在,但排列顺序有问题;应通过举例子顺一遍,应该先让指针右移递加,一旦和满足要求(>=target),首先计算此时长度,比较选取和上一次的最小值;先删除此时左指针元素,减小长度用于下一次判断;然后在处理left左指针,left++(先处理left会导致长度不是此时符合要求的长度;以及)
关键点:滑动窗口,分清左右两指针的作用,因此判断清楚循环递增变量用哪一个
重点理解while循环内的逻辑
答案:
int minSubArrayLen(int target, int* nums, int numsSize) {
int sum = 0;
int left = 0;
int right = 0;
int length = INT_MAX;
for(right=0;right<numsSize;right++){
printf("%d %d", right, sum);
sum = sum + nums[right];
while(sum>=target){
if(length>=(right - left+1)){
length = right - left+1;
}
sum = sum - nums[left];
left++;
}
}
return length == INT_MAX ? 0 : length;
}
59.螺旋矩阵II
题目链接:. - 力扣(LeetCode)
讲解链接:代码随想录 (programmercarl.com)
视频链接:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili
问题所在:会写for,但是不知道怎么转起来,走一圈一般是while
关键点:保持统一规则,循环不变量,类似二分法规定好区间定义;
首先转几圈?n/2圈,如果n为奇数(n%2==1),最后单独赋值;
考虑起始和终止位置,用while让它转起来
答案:(先复制下来,动态分配内存还不会写)
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
//初始化返回的结果数组的大小
*returnSize = n;
*returnColumnSizes = (int*)malloc(sizeof(int) * n);
//初始化返回结果数组ans
int** ans = (int**)malloc(sizeof(int*) * n);
int i;
for(i = 0; i < n; i++) {
ans[i] = (int*)malloc(sizeof(int) * n);
(*returnColumnSizes)[i] = n;
}
//设置每次循环的起始位置
int startX = 0;
int startY = 0;
//设置二维数组的中间值,若n为奇数。需要最后在中间填入数字
int mid = n / 2;
//循环圈数
int loop = n / 2;
//偏移数
int offset = 1;
//当前要添加的元素
int count = 1;
while(loop) {
int i = startX;
int j = startY;
//模拟上侧从左到右
for(; j < startY + n - offset; j++) {
ans[startX][j] = count++;
}
//模拟右侧从上到下
for(; i < startX + n - offset; i++) {
ans[i][j] = count++;
}
//模拟下侧从右到左
for(; j > startY; j--) {
ans[i][j] = count++;
}
//模拟左侧从下到上
for(; i > startX; i--) {
ans[i][j] = count++;
}
//偏移值每次加2
offset+=2;
//遍历起始位置每次+1
startX++;
startY++;
loop--;
}
//若n为奇数需要单独给矩阵中间赋值
if(n%2)
ans[mid][mid] = count;
return ans;
}
区间和
讲解链接:58. 区间和 | 代码随想录 (programmercarl.com)
关键点:
利用前缀和,遍历一遍,边读取边加和,前缀和相减得到区间和。
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
scanf("%d", &n);
int *vec = (int *)malloc(sizeof(int) * n);
int *p = (int *)malloc(sizeof(int) * n);
int presum = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &vec[i]);
presum += vec[i];
p[i] = presum;
}
int a, b;
while (scanf("%d %d", &a, &b) == 2) {
int sum;
if (a == 0) {
sum = p[b];
} else {
sum = p[b] - p[a - 1];
}
printf("%d\n", sum);
}
free(vec);
free(p);
return 0;
}
开发商购买土地
讲解链接:44. 开发商购买土地 | 代码随想录 (programmercarl.com)
关键点:同样利用区间和的思想,计算好每一行或者每一列的和,做差即可
第一章总结 - 数组
卡哥总结:代码随想录 (programmercarl.com)
另外需要注意的点:
1.掌握好数组的地址、值、下标之间的关系
2.动态分配内存
3.for和while的选用
4.二维数组的格式
5.思考复杂度是怎么得来的
第二天感受:
实际上昨天被209卡住了,明明要素都在,运行不正确,有点心浮气躁,一行一行对比也没发现问题;第三天才解决,逐行比较发现逻辑错误,处理指针的语句先后问题----一定要梳理好整个过程的逻辑,如果过于抽象难以想像,建议用图形或者例子辅助理解;一遍很难全部明白,进度有点慢了,没懂的地方要来回看两三遍;看过视频理解逻辑不代表会写,很多细节需要注意的,定期看题目回想大概要怎么做,形成一个惯性或者解题流程。
ps:代码出错的时候--1.逐行对比 2.看不懂丢给GPT 3.学会自己debug打印参数(很尴尬的是C语言printf我加了&,打印一堆地址出来) 4.群里描述清楚请教大佬解答