代码随想录算法训练营第二天 | 209.长度最小的子数组、 59.螺旋矩阵II

209.长度最小的子数组

滑动窗口解法,关键点在于根据当前子序列长度和大小,不断调节子序列位置。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int size = nums.size();
        int sum=0;
        int i=0;
        int result = INT32_MAX;
        for(int j=0;j<size;j++){
            sum+=nums[j];
            while(sum>=target){
                int count=j-i+1;
                sum-=nums[i];
                i++;
                result= result > count ? count : result;
            }
        }
        return result = result < INT32_MAX ? result : 0;
    }
};

59.螺旋矩阵II

关键点在于坚持循环不变量原则,也就是不坚持同一区间,如左闭右开,其次循环次数为n/2,当n为奇数时,单独给中心点赋值即可。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n));
        int startx = 0;
        int starty = 0;
        int count=1;
        int loop = n / 2;
        int Offset = 1;
        while(loop--){
            int i = startx;
            int j = starty;
            for(j; j < n-Offset; j++){
                res[i][j]=count;
                count++;
            }
            for(i; i < n-Offset; i++){
                res[i][j]=count;
                count++;
            }
            for(j; j > starty; j--){
                res[i][j]=count;
                count++;
            }
            for(i; i > startx; i--){
                res[i][j]=count;
                count++;
            }
            Offset++;
            startx++;
            starty++;
        }
        if(n%2==1){
            res[n/2][n/2]=count;
        }
        return res;
    }
};

区间和

题目描述

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

输入描述

第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间下标:a,b (b > = a),直至文件结束。

输出描述

输出每个指定区间内元素的总和。

输入示例
5
1
2
3
4
5
0 1
1 3
输出示例
3
9
提示信息

数据范围:
0 < n <= 100000

这题关键点在于通过一个数组其第i项接收前i项和sum,还有scanf和printf在大量输入输出时远比cin还有cout耗时少

#include<iostream>
#include<vector> 
using namespace std;
 
int main(){
	int n;
	int temp=0;
	cin>>n;
	vector<int> A(n);
	vector<int> B(n);
	for(int i=0;i<n;i++){
		scanf("%d",&A[i]);
		temp+=A[i];
		B[i]=temp;
	}
	int a,b;
	int sum=0;
	while(~scanf("%d%d", &a, &b)){
		if (a < 0 || b >= n || a > b) {
            cout << "Invalid range" << endl;
            continue;
        }
		if(a==0){
			sum=B[b];
		}else{
			sum=B[b]-B[a-1];
		}
		printf("%d\n", sum);
	}
	return 0;
} 

开发商购买土地

题目描述

在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。 

现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。

然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。 

注意:区块不可再分。

输入描述

第一行输入两个正整数,代表 n 和 m。 

接下来的 n 行,每行输出 m 个正整数。

输出描述

请输出一个整数,代表两个子区域内土地总价值之间的最小差距。

输入示例
3 3
1 2 3
2 1 3
1 2 3
输出示例
0
提示信息

如果将区域按照如下方式划分:

1 2 | 3
2 1 | 3
1 2 | 3 

两个子区域内土地总价值之间的最小差距可以达到 0。

数据范围:

1 <= n, m <= 100;
n 和 m 不同时为 1。

解题关键点还是与区间和所用知识点相同,都为求前缀和,在将前缀和进行比较。

#include<iostream>
#include<vector> 
#include<climits>
#include<cmath>
using namespace std;
 
int main(){
	int n,m;
	cin>>n>>m;
	int sum=0;
	vector<vector<int> > A(n,vector<int>(m));
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>A[i][j];
			sum+=A[i][j];
		}
	}
	vector<int> row(n);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			row[i]+=A[i][j];
		}
	}
	
	vector<int> col(m);
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			col[j]+=A[i][j];
		}
	}
	
	int result = INT_MAX;
	int rowCut=0;
	for(int i=0;i<n;i++){
		rowCut+=row[i];
		result=min(result,abs(sum-rowCut-rowCut));
	}
	
	int colCut = 0; 
	for(int j=0;j<m;j++){
		colCut+=col[j];
		result=min(result,abs(sum-colCut-colCut));
	}
	cout<<result<<endl;
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值