1.1 977有序数组的平方-代码随想录
1.2 977有序数组的平方-卡哥B站视频讲解
1.3 209长度最小的子数组-代码随想录
1.4 209长度最小的子数组-卡哥B站视频讲解
1.5 59螺旋矩阵 II-代码随想录
1.6 59螺旋矩阵 II-卡哥B站视频讲解
- sort方法一开始写错了
- 时间复杂度认为两种解法都是线性复杂度,这是错误的,因为我不清楚sort方法是什么排序,并且在计算是,没有算进暴力解法中
- 看了解法后,没理解k- -能放进result[k]的原因
- 连续条件不知道怎么写,看下面代码
- 没有考虑滑动窗口->双指针的不熟悉
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int child_len = 0, total = 0; // 声明子数组长度 和 元素相加总值
for(int i=0; i<nums.size(); i++){ // 遍历
// 数组中第i个元素小于target
if(nums[i]<target){
// 如何判断是连续的?????
//连续的话
total += nums[i]; // 计算总值
}
// 数组中第i个元素等于target
else if(nums[i]==target){
// 直接返回1长度,
// 不能是child_len++,
// 考虑数组内有几个与target相等的元素之情况
return 1;
}
// 数组中第i个元素大于target
else continue; // 跳过第i个,检查下一个
}
// 全部元素加起来小于target,或者全部元素都大于target, 返回0
return child_len;
}
};
- 忘记如何声明二维数值,其实就是嵌套一下一维的声明。
- offset定义一开始不太清楚,实际写的时候理解了很久
- 4个边for loop时,j
Code1: 977暴力解法
时间复杂度: O(n+nlog n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
// 1. 数组中每个元素乘方
for(int i=0; i<nums.size(); i++){
nums[i] *= nums[i];
}
// 2. 排序 - 哪种排序?
sort(nums.begin(), nums.end());
// 3. 返回数组
return nums;
}
};
Code2: 977双指针解法但未想通k- -为何可以放在result[k]中
时间复杂度:** O(n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1; // k是最终数组的最后一个index
vector<int> result(nums.size(), 0); // 声明最终数组
// i是左边界index,j是右边界index,左边不能超过右边
for(int i=0, j=nums.size()-1; i<=j;){
// 最左边元素的乘方大于最右边元素的乘方
if(nums[i]*nums[i]>nums[j]*nums[j]){
// 最终数组的最后一个元素是大的一方(左)
result[k] = nums[i] * nums[i];
i++; // 左边界index右移(往后)一位
k--; // 最终数组的最后一个元素已有,index往前一位
}
else { // 最左边元素的乘方小于等于最右边元素的乘方
// 最终数组的最后一个元素是大的一方(右)
result[k] = nums[j] * nums[j];
j--; // 右边界index左移(往前)一位
k--; // 最终数组的最后一个元素已有,index往前一位
}
}
return result;
}
};
Code3: 977双指针解法
时间复杂度:O(n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1; // k是最终数组的最后一个index
vector<int> result(nums.size(), 0); // 声明最终数组
// i是左边界index,j是右边界index,左边不能超过右边
for(int i=0, j=nums.size()-1; i<=j;){
// 最左边元素的乘方大于最右边元素的乘方
if(nums[i]*nums[i]>nums[j]*nums[j]){
// 最终数组的最后一个元素是大的一方(左)
// 先获得最后一位元素的值,然后做-1,所以用k--
result[k--] = nums[i] * nums[i];
i++; // 左边界index右移(往后)一位
}
else { // 最左边元素的乘方小于等于最右边元素的乘方
// 最终数组的最后一个元素是大的一方(右)
result[k--] = nums[j] * nums[j];
j--; // 右边界index左移(往前)一位
}
}
return result;
}
};
Code4: 209暴力解法-2个loop
时间复杂度: O( N 2 N^2 N2)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX; // 最终连续子数组的长度
int total = 0; // 连续子数组元素相加总和
int subLen = 0; // 当前连续子数组的长度
for(int i=0; i<nums.size(); i++){ // 子数组的头index
total = 0; // 新一轮连续子数组,得重置总和
for(int j=i; j<nums.size(); j++){ // 子数组的尾index
total += nums[j]; // 子数组中元素加进总和
if(total>=target){ // 如果总和大于等于目标,
subLen = j - i + 1; // 计算当前子数组长度
// 比较当前子数组长度与之前存进result符合条件的子数组的长度
// 小的存进result
result = subLen < result ? subLen : result;
break; // 已经存进了最短长度,此子序列结束,跳出j-loop
}
}
}
// 如果result未发生变化,说明没有满足条件的数组,结果为0;有变化,则输出
return result == INT32_MAX ? 0 : result;
}
};
Code5: 209滑动窗口-双指针
时间复杂度: O(N)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX; // 最短连续子数组的长度
int i = 0; // 滑动窗口起点index
int total = 0; // 滑动窗口内元素总和
int subLen = 0; // 当前滑动窗口的长度
for(int j=0; j<nums.size(); j++){ // 滑动窗口终点index
total += nums[j]; // 更新总数,将当前元素加进来
while(total>=target){ // 当子数组元素总和大于等于target
subLen = j - i + 1; // 计算当前滑动窗口的长度
// 之前的长度和当前的长度,哪个小取哪个
// 注意,这里滑动窗口的终点index不会改变
result = result < subLen ? result : subLen;
// 精髓。总和减去当前元素后,窗口起点index右移,窗口长度自动缩小
total -= nums[i++];
}
}
// result未赋值,则没有符合要求的连续子数组,返回长度0;result赋值了,则返回
return result == INT32_MAX ? 0 : result;
}
};
Code6: 59循环不变量原则-左闭右开
时间复杂度: O( N 2 N^2 N2)
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> mat(n, vector<int>(n, 0)); // 声明二维数组
int startx = 0, starty = 0; // 声明起始点位置
int loop = n / 2; // 一共经历几次循环,相当于有多少圈
int mid = n / 2; // 奇数n时,矩阵中点没填充到,需要声明中点位置,最后填充
int count = 1; // 填充的数字
int offset = 1; // 每边收缩的数目,要在4边loop后更新
int i, j;
while(loop--){ // 每一轮4边填充后,循环数(圈数)减少,直至0不再填充(退出)
// 更新每次i,j
//i = startx;
//j = starty;
// 一轮填充4条边 -> 4个for loop ,左闭右开原则
// 上边,j变(从左往右递增)i不变
for(j=starty; j<n-offset; j++)
mat[startx][j] = count++;
// 右边,i变(从上往下递增)j不变
for(i=startx; i<n-offset; i++)
mat[i][j] = count++;
// 下边,j变(从右往左递减)i不变
for(; j>starty; j--)
mat[i][j] = count++;
// 左边,i变(从下往上递减)j不变
for(; i>startx; i--)
mat[i][j] = count++;
// 更新起始点位置,准备下一此循环
startx++;
starty++;
// 更新收缩数目,增加1位要收缩的
offset++;
}
// 循环结束后,判断n是否为奇数,是则填充中间位置
if(n%2)
mat[mid][mid] = count;
return mat;
}
};