977.有序数组的平方
第一想法是,对原数组元素进行绝对值排序再平方,或者先平方再排序。问题是如何排序?
看了讲解之后,明白自己忽视了题目中的原始要求:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。所以在排序方法上可以不用全部重新排序,可以利用它原有的格式,最大值只可能出现在最左端或者最右端,利用双指针方法对它进行排序。
冒泡排序
能通过测试样例,但是超出时间限制。
int* sortedSquares(int* nums, int numsSize, int* returnSize)
{
*returnSize = numsSize;
int i;
int j;
int m;
int n;
int a;
int* ans = (int*)malloc(sizeof(int) * numsSize);
for(m = 0; m < numsSize; m++){
n = m;
ans[m] = nums[n] * nums[n];
}
for(i = 0; i < numsSize - 1; i++){
for(j = 0; j < numsSize - 1; j++){
if(ans[j] > ans[j+1]){
a = ans[j];
ans[j] = ans[j+1];
ans[j+1] = a;
}
}
}
return ans;
}
双指针(神一样好用精妙的思想)
关键点在于“有序数组”,本身给提供的数组就是按照顺序排列的,因此最大值最小值只有可能出现在两端,不会出现在中间。
int* sortedSquares(int* nums, int numsSize, int* returnSize){
// returnSize代表返回的数组大小 这样处理
*returnSize = numsSize;
//因为返回的数组大小就是原数组大小
int right = numsSize - 1;
int left = 0;
//自己再定义一个数组作为最后返回的数组 通过以下的方式来定义
int* ans = (int*)malloc(sizeof(int) * numsSize);
//意思是通过malloc这个动态规划内存的方式 为什么通过这种方式 别的方式不行吗
int i;
for(i = numsSize - 1; i >= 0; i--){
int l = nums[left] * nums[left];
int r = nums[right] * nums[right];
if(l > r){
ans[i] = l;
left = left + 1;
//注意这里左右指针的加减
}
else{
ans[i] = r;
right = right - 1;
//注意这里左右指针的加减
}
}
return ans;
}
Dynamic Memory Allocation
动态规划是指运行时数据结构(比如数组)大小的改变。C语言提供了一些方法解决这个任务。4个定义在<stdlib.h>下的库函数:malloc()calloc()free()realloc()
malloc(m指Memory alloc指Allocation)可以动态规划出指定大小的一块独立大块内存,返回一个空类型指针(可以被转换为任何类型的指针),语法规则如下。
//Syntax:
ptr = (cast-type*) malloc(byte-size)
//Example:
int* ans = (int*)malloc(sizeof(int) * 100);
//int的大小是4字节,malloc会分配400个内存字节
//指针ans是内存字节的第1个字节
//如果空间不足,会返回空指针
![](https://i-blog.csdnimg.cn/blog_migrate/2845fce3c17fd8ceff8325780a82199d.png)
https://www.google.com/amp/s/www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/amp/
209.长度最小的子数组
利用双指针思想
int minSubArrayLen(int target, int* nums, int numsSize){
//初始化最小长度为INT_MAX
int minLength = INT_MAX;
int sum = 0;
int left = 0, right = 0;
//右边界向右扩展
for(; right < numsSize; ++right) {
sum += nums[right];
//当sum的值大于等于target时,保存长度,并且收缩左边界
while(sum >= target) {
int subLength = right - left + 1;
minLength = minLength < subLength ? minLength : subLength;
sum -= nums[left++];
}
}
//若minLength不为INT_MAX,则返回minLnegth
return minLength == INT_MAX ? 0 : minLength;
}
59.螺旋矩阵II
通过一个while循环内嵌for循环解决螺旋填充数字问题。
引入了循环圈数loop变量,loop = n / 2
引入了偏移数offset
引入每次循环的起始位置startX startY
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
int nums[n][n];
int s = 1;
int i,j,k;
//i为行数 j为列数 s为填充的数字
int startX = 0;
int startY = 0;
//每次循环的起始位置
*returnSize = n;
*returnColumnSizes = (int*)malloc(sizeof(int) * n);
int** ans = (int**)malloc(sizeof(int*) * n);
int loop = n / 2;//循环的圈数
int offset = 1;//偏移数
for(i = 0; i < n; i++) {
ans[i] = (int*)malloc(sizeof(int) * n);
(*returnColumnSizes)[i] = n;
}
while(loop > 0){
i = startX;
j = startY;
for( ; j < startY + n - offset; j++){
ans[startX][j] = s;
s++;
}
for( ; i < startX + n - offset; i++){
ans[i][j] = s;
s++;
}
for( ; j > startY; j--){
ans[i][j] = s;
s++;
}
for( ; i > startX; i--){
ans[i][j] = s;
s++;
}
//偏移值每次加2
offset+=2;
//遍历起始位置每次+1
startX++;
startY++;
loop--;
}
if(n % 2 != 0){
ans[n/2][n/2] = n * n;
}
return ans;
}