代码随想录算法训练营43期 | Day 2——209. 长度最小的子数组、59.螺旋矩阵、区间和

6 篇文章 0 订阅

代码随想录算法训练营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,请计算该数组在每个指定区间内元素的总和。

解题思路

前缀和思想:

  1. 输入n个数,用一个数组保存,得到array数组;
  2. sum记录前n项数组之和;
  3. 使用p[i]数组,记录前n项和;
  4. 输入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;
}



  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值