目录
一:数组基础知识
1.数组的含义:数组是存放在 连续内存空间 上的 相同类型数据 的集合。
类比于结构体的概念:存储不同类型的变量。
2.注意:
、 (1):数组空间的内存地址是连续的
(2):数组元素不能删除,只能覆盖。(这是比较重要的一点,如双指针)
(3):二维数组在c++地址空间上是连续的。
二:部分题目分析
int minSubArrayLen(int target, int* nums, int numsSize){
int i=0,j;
int result=INT_MAX;//注意知识点
//初始化看作一个相当大的数
int sum=0,sublen;//定义和 以及子数组的长度
for(j=0;j<numsSize;j++)//进行终止位置的遍历
{
sum=sum+nums[j];
while(sum>=target)//判断和是否大于目标和,若是则进行起始位置的查找
{
sublen=j-i+1;//计算子数组长度,注意+1
result=result<sublen?result:sublen;
//采用条件判断其子数组的长度是否小于最大数组长度
sum=sum-nums[i];
//精髓之处,起始位置依次判断
i++;
}
}
return result==INT_MAX?0:result;//是否返回为0
}
本题使用滑动窗口:不断调整终止位置和起始位置(与双指针的思考方式类似)
方法:先进终止位置的查找,是其和>=目标值,再移动起始位置,使和减去起始位置,并考虑其子数组长度。
精髓:调整起始位置,没有使用for循环,而是采用了while循环。
注意:需要比较子数组长度是否小于最大长度(引出知识点),并且需要保证子数组存在且有长度,否则返回为0。
循环不变量原则
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
// 使用vector定义一个二维数组
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
int loop = n / 2;
// 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int mid = n / 2;
// 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1; // 用来给矩阵中每一个空格赋值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i,j;
while (loop --) {
i = startx;
j = starty;
// 下面开始的四个for就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j = starty; j < n - offset; j++) {
res[startx][j] = count++;
}
// 模拟填充右列从上到下(左闭右开)
for (i = startx; i < n - offset; i++) {
res[i][j] = count++;
}
// 模拟填充下行从右到左(左闭右开)
for (; j > starty; j--) {
res[i][j] = count++;
}
// 模拟填充左列从下到上(左闭右开)
for (; i > startx; i--) {
res[i][j] = count++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2) {
res[mid][mid] = count;//此时的cout值已经+1
}
return res;
}
};
代码是抄写的随想录上面的,还不是很会自己写,理解了代码的意思了。
一开始我就理解错了题目含义,尤其是在这个形成螺旋状上面以为题目表示的意思是像下面那道题的类似是顺时针排序,但是没想到这道题是一个正方形走完,再进行下一个。
查了leetcode的题解,增加了注释,自己的理解
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize) {
if (matrixSize == 0 || matrixColSize[0] == 0) //行列都不等于0
{
*returnSize = 0;
return NULL;
}
int rows = matrixSize, columns = matrixColSize[0];//行 列
int total = rows * columns;//所有的数
int* order = malloc(sizeof(int) * total);//定义返回的指针
*returnSize = 0;//相当于一个计数的
int left = 0, right = columns - 1, top = 0, bottom = rows - 1;
//左边 右边 列-1 顶端 底部为行-1
while (left <= right && top <= bottom) //不重复
{
//进行第一行从左到右的赋值
for (int column = left; column <= right; column++) {
order[(*returnSize)++] = matrix[top][column];//将原来的数组赋值给新数组
}
//右侧从上到下
for (int row = top + 1; row <= bottom; row++) {
order[(*returnSize)++] = matrix[row][right];
}
//方便第二次循环,判断是否有底部和左边
if (left < right && top < bottom) {
//底部从右到左
for (int column = right - 1; column > left; column--) {
order[(*returnSize)++] = matrix[bottom][column];
}
//左侧从下到上
for (int row = bottom; row > top; row--) {
order[(*returnSize)++] = matrix[row][left];
}
}
left++;//向右移
right--;//左移动
top++;//下移动
bottom--;//向上移动
}
return order;
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/spiral-matrix/solution/luo-xuan-ju-zhen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个题不是一个正方形或者是长方形,而更多的是根据输入的数组来输出,所以这里要有if条件的判断。这两道题很相似,用到的方法也都是四条边分别输出,采用循环不变量原则,还需再多加练习。
三:本章涉及知识点
知识点1:使用INT_MAX和INT_MIN时,需要使用 #include<limits.h>
INT_MAX=2^31-1,INT_MIN=-2^31.//初始化看作一个相当大的数或者相当小的数
知识点2:双指针(快慢指针法)
通过一个快指针和一个慢指针在一个for循环下完成两个for循环的工作
下面为代码样例:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (val != nums[fastIndex]) {
nums[slowIndex++] = nums[fastIndex];//快慢指针的体现之处
}
}
return slowIndex;
}
};
知识点3:二分法
1.前提条件:
无重复元素
按照顺序排列(有序数组)
2.解题方式(循环不变量)
(1)左闭右闭 [ ]
while(left<=right)
left=mid+1 right=mid-1;
(2) 左闭右开 [ )
while(left<right) //这里使用<是因为=没有意义,右边取不到
left=mid+1 right=mid;
知识点4:c语言为:malloc函数 在函数中引入新的指针变量,动态分配内存区域。
malloc函数的返回实际是无类型指针,必须在前面加上指针类型强制转换才能使用
指针类型=(指针类型*)malloc(sizeof(指针类型)*数据数量)//计算字节数
int* ans = (int*)malloc(sizeof(int) * numsSize);
四:刷题感受
因为之前学习的是c语言,并没有学习关于c++相关的知识,但是代码随想录网站以及力扣等大多使用c++,所以也在c和c++ 的过渡期,对于此次数组的学习,主要在于算法以及各种特殊函数,如nums.size(),malloc函数,vector定义数组,双指针,循环不变量,滑动窗口。收获还是很多,望坚持算法的练习。