代码随想录算法训练营43期 | Day 2
209. 长度最小的子数组
leetcode链接
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
解题思路
- 滑动窗口(推荐)
- 暴力破解
暴力破解:
两个for循环遍历每一种出现的情况,然后不断的寻找符合条件的子序列,时间复杂度很明显是O(n^2)
滑动窗口法:
就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果
类似双指针法,取两个指针之间的区间;
取 i 为起始指针,取 j 为终止指针,j 遍历数组,当 i 与 j 之间的区间的值大于target的值的时候,起始指针开始向后移动;
用一个for循环表示下标终止的位置,
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;//定义result为极大值
int sum = 0; //定义sum的值初始化为0
int i = 0; //定义起始指针
int sublen = 0; //定义最小子数组长度
//定义终止指针, j 遍历整个数组
for(int j = 0; j < nums.size(); j++)
{
sum += nums[j];//数组元素和
//定义起始指针,起始指针开始移动条件为sum>=target;
while(sum>=target)
{
sublen = (j - i) + 1; //最小子数组长度
if(result > sublen) //判断最小子串长度
{
result = sublen; //result赋值为sublen
}
sum = sum - nums[i]; // 区间和减去i所在的值
i++; // i 不断增加,改变子区间的范围
}
}
if(result==INT32_MAX)
// 注意 return 值,如果没有变化,说明没有符合的子区间,返回0
{
return 0;
}else
{
return result;
}
}
};
59.螺旋矩阵
leetcode链接
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
解题思路
循环不变量:每一条边的边界处理规则保持一致,螺旋矩阵要一圈一圈去循环;
不变量:每一条边的处理规则左闭右开 [ ) ;
坚持一个原则:左闭右开
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n, vector<int>(n));
int left = 0;
int right = n - 1;
int up = 0;
int down = n - 1;
int num = 1;
while(num<=n*n)
{
//左->右
for(int i = left;i<=right;i++)
{
result[up][i] = num;
num++;
}
up++;//行数增加
//从上往下
for(int i = up;i<=down;i++)
{
result[i][right] = num;
num++;
}
right--;
//从右往左运动
for(int i = right;i>=left;i--)
{
result[down][i] = num;
num++;
}
down--;
//从下往上
for(int i = down;i>=up;i--)
{
result[i][left] = num;
num++;
}
left++;
}
return result;
}
};
区间和
链接
给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。
解题思路
前缀和思想:
- 输入n个数,用一个数组保存,得到array数组;
- sum记录前n项数组之和;
- 使用p[i]数组,记录前n项和;
- 输入a和b,a到b之间的和为 b - (a - 1),if(a==0) result = p[b];
#include<iostream>
#include<vector>
using namespace std;
int main()
{
// 输入n个数
int n, a, b;
cin>>n;
//保存输入的n个数的数组
vector<int> array(n);
// 保存前缀和的数组
vector<int> p(n);
// sum用于记录前n项数之和
int sum = 0;
for(int i = 0;i<n;i++)
{
cin>>array[i];
//输入长度为n数组
sum = sum + array[i];
//前缀和数组
p[i] = sum;
}
//输入a和b
while(cin>>a>>b)
{
int result;
if(a==0)
{
result = p[b];
}else
{
result = p[b]-p[a-1];
}
cout<<result<<endl;
}
return 0;
}