977.有序数组的平方
一、做题感受&第一想法
犯的小错:
①一开始returnSize没赋值,导致没有输出。
②重复使用了i,但是第二次使用时while循环前没有给i赋初值。
③定义数组时,数组大小用了变量(C语言不允许这样),导致报错。
第一想法:双指针(但略麻烦,还可以改进。麻烦主要在各种边界的判断上。)
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
int i = 0, j = -1, k = 0;
int *newNums = (int*)malloc(sizeof(int)*numsSize);
for(i = 0; i < numsSize; i++) //找到负数正数的分界点,记录在j中
{
if(nums[i] < 0){
j++;
nums[i] = nums[i]* nums[i];
}
else if(nums[i] >= 0)
{
nums[i] = nums[i]* nums[i];
}
}
i = j + 1; //重复使用了i作为循环变量,不要忘记初始化
while((j >= 0) || (i < numsSize)){ //当正数、负数有一方没有被完全遍历时,继续循环
if((j >= 0 && i < numsSize && nums[i] < nums[j]) || (j < 0 && i < numsSize)){
newNums[k] = nums[i];
k++;
i++;
}
else if((j >= 0 && i < numsSize && nums[i] >= nums[j]) || (j >= 0 && i >= numsSize)){
newNums[k] = nums[j];
k++;
j--;
}
}
* returnSize = numsSize; //leetcode平台不要忘记赋值returnSize。
return newNums;
}
二、学习文章后收获
1.双指针法:
- 一头一尾开始,往中间遍历 (因为最大的一定在两边)
- 比较时运用归并排序的思想。需要额外的数组空间,空间复杂度O(n)。
- 返回的数组是从后往前遍历的(一个以后可借鉴的思路),因为归并排序排出来的是从大到小。
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
int i = 0, j = numsSize - 1, k = numsSize - 1;
int * returnNums = (int *) malloc(sizeof(int)*numsSize);
while(i<=j){
if(nums[i]*nums[i] < nums[j]*nums[j] ){
returnNums[k] = nums[j] * nums[j];
k--;
j--;
}
else{
returnNums[k] = nums[i] * nums[i];
i++;
k--;
}
}
* returnSize = numsSize;
return returnNums;
}
三、实现过程中的困难
1.C语言中直接定义数组,数组大小不能用变量。(但可以通过malloc解决)
报错:
solution.c: In function ‘sortedSquares’
Line 6: Char 5: error: variable-sized object may not be initialized [solution.c]
9 | int newNums[numsSize] = {0};
| ^~~
209.长度最小的子数组
一、做题感受&第一想法
只想到暴力解法。最后超出时间限制。
二、学习文章后收获
1.双指针:滑动窗口法
#define INT_MAX 100001
int minSubArrayLen(int target, int* nums, int numsSize) {
int j = 0, i = 0, length = INT_MAX, sum = 0;
for( j = 0; j < numsSize; j++ ){
sum += nums[j];
while(sum >= target){
length = (length > j-i+1) ? (j-i+1) : length;
sum -= nums[i];
i++;
}
}
return (length == INT_MAX) ? 0 : length;
}
- j:滑动窗口的结束位置。一直加加,直到最后。
- i:滑动窗口的开始位置。只有需要时才更新。
- length:记录找到的最小滑动窗口的长度。每找到一个滑动窗口就更新一次。
三、实现过程中的困难
1.灵活使用 ? :
运算符
简单的条件判断可用该运算符。可以减少分支语句的使用。
2.有时可设置极大值MAX,以便于编程。
59.螺旋矩阵Ⅱ
一、做题感受&第一想法
①不会申请二维数组。
②螺旋矩阵赋值时,对某些元素重复赋值了(旋转换方向时,把四个角上的元素重复赋值了,属于逻辑上没想清楚的错误。)
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {
*returnSize = n;
*returnColumnSizes = (int *)malloc(sizeof(int)*n);
int ** matrix = (int** )malloc(sizeof(int*) * n);
for(int i = 0; i < n; i++){
matrix[i] = (int *)malloc(sizeof(int)*n);
(*returnColumnSizes)[i] = n;
}
int k = 1, t = 0, i = 0;
while(k<=n*n){
for(i = t; i < n-t && k <= n*n; i++){
matrix[t][i] = k;
k++;
}
for(i = t+1; i < n-t && k <= n*n; i++){
matrix[i][n-t-1] = k;
k++;
}
for(i = n-t-1-1; i >= t && k <= n*n; i--){
matrix[n-t-1][i] = k;
k++;
}
for(i = n-t-1-1; i >= t+1 && k <= n*n; i--){
matrix[i][t] = k;
k++;
}
t++;
}
return matrix;
}
二、学习文章后收获
三、实现过程中的困难
1.关于c语言中申请二维数组
int ** p = (int **)malloc(sizeof(int*) * row);
for(int i = 0; i < row; i++){
p[i] = (int *)malloc(sizeof(int) * col);
}
2.leetcode平台下的二维数组大小返回值
//Return an array of arrays of size *returnSize.
//The sizes of the arrays are returned as *returnColumnSizes array.
*returnSize = n; //共有几个数组(行数)
*returnColumnSizes = (int *)malloc(sizeof(int)*n);
int ** matrix = (int** )malloc(sizeof(int*) * n);
for(int i = 0; i < n; i++){
matrix[i] = (int *)malloc(sizeof(int)*n);
(*returnColumnSizes)[i] = n; //记录每个数组的大小,即每个数组的元素个数(列数)
}
3.数组、二维数组、指针的关系
int arr[3] = {1,2,3};
int* pa = arr;
(1)数组地址&arr
、数组名arr
、数组第一个元素地址arr[0]
,三者都是“地址”值,三者相同!
(2)数组名arr
可以认为是指针常量,无法改变。
(3)对于“指向数组元素的指针”pa
:
①可以用pa[0] pa[1] pa[2]
来取数组元素。
②也可以pa = pa + 1
来改变pa的指向,此时pa指向第二个元素pa[1]
(因为对指针变量加减n,实际地址改变n*sizeof(类型)的大小。)。
③也可以用*pa
来取数组元素。
int arr[3] = {1,2,3};
int (*parr)[] = &arr;
(4)对于“指向数组类型的指针”parr
:
①定义格式:int (*parr)[] = &arr
(为什么加括号?因为[]优先级高于*。)
注:截图来自up主:哈哈哈哈栋。
链接:link
②如何取数组元素:(*parr)[0], (*parr)[1], (*parr)[2]
(可以理解为*parr == arr)
(5)“指针数组”(数组的元素是指针)p
:
int a = 1, b = 2;
int *p[2] ={&a , &b};
①如何取元素:*p[0], *p[1]
(6)混合型:
要想取出元素值:*(*parr)[0], *(*parr)[1], *(*parr)[2]
。
(二维数组,待补充。)