977.有序数组的平方
题目链接:力扣-977.有序数组的平方
思路:
第一眼看到这道题,就想到了用昨天学的双指针法,很可惜编译失败,看完卡哥的视频之后,知道自己卡在了什么地方,没有想到数组中的元素可能为负数。了解完具体思路后,立马动手去编写程序,成功通过了编译。
数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
i指向起始位置,j指向终止位置。
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。
如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i]; 。
如动画所示:
卡哥视频链接:https://www.bilibili.com/video/BV1QB4y1D7ep
文章讲解:代码随心录
代码:
int* sortedSquares(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
int* ans = (int*)malloc(sizeof(int) * numsSize);
int i = numsSize - 1;
int left = 0;
int right = numsSize - 1;
while(left <= right){
if(nums[left] * nums[left] > nums[right] * nums[right]){
ans[i--] = nums[left] * nums[left];
left++;
}
else{
ans[i--] = nums[right] * nums[right];
right--;
}
}
return ans;
}
力扣上有一个总结的很好的题解,利用了多种排序和双指针的方法,先贴出来供大家一起学习,正好能复习以下各种排序算法。
209.长度最小的子数组
题目链接:力扣-209. 长度最小的子数组
思路:
这道题曾经做过,如今再来做依然写不出来......
思考了十几分钟无思路后,继续看卡哥视频讲解学习。
该题有两种解法,一种是暴力解,第二种是利用滑动窗口的方法来解题,这也是数组中比较重要的解法,个人感觉像是暴力解法的优化,还是用到了两个循环,看视频时有弹幕说可以用if,暂时还没想出来,明天再看看。
所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
图示更能方便理解,照例附上卡哥视频及文章讲解链接。
大致思路是,先固定滑动窗口的起始位置 i ,用终止位置 j 进行索引,当该区间内所有元素相加大于等于目标数时,移动起始位置 i 。若新区间元素之和小于目标数,则继续移动 j ,直到大于等于目标数。重复以上操作,直到寻找到长度最小的子数组。
代码:
int minSubArrayLen(int target, int* nums, int numsSize){
int ans = INT_MAX;
int left = 0;
int right = 0;
int sum = 0;
for(; right < numsSize; right++){
sum += nums[right];
while(sum >= target){
int length = right - left + 1;
ans = ans < length? ans : length;
sum -= nums[left++];
}
}
return ans == INT_MAX? 0 : ans;
}
59螺旋矩阵II
题目链接:力扣-59. 螺旋矩阵 II
思路:
看到这个题时确实没什么思路,看完视频和文章讲解后,能理解思路,但还不能完全写出完整代码来,打算明天再仔细琢磨一下。
附上学习的链接:
https://www.bilibili.com/video/BV1SL4y1N7mV
代码:
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;
}
总结
今天的题总体难度很大,加上今天时间有限,这篇博客写得不是很好,明天我会抽出时间来好好总结完数组的所有题目,包括附加题,对这两天的博客再度更新,将题目都重新归纳整理。