** 209.长度最小的子数组**
leetcode链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
题目描述:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
核心思路:暴力法或者滑动窗口
暴力法:时间复杂度O(n2),本题会造成超时
点击查看代码
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;//定义为int的最大取值,用于后续判断
int length,sum;
for(int i = 0;i < nums.size();i++){
sum = 0;
for(int j = i;j<nums.size();j++){
sum += nums[j];
if(sum >= target){
length = j - i + 1;
result = result < length ? result :length;//当条件成立时,赋值为result,条件不成立则赋值length
break;
}
}
}
return result == INT32_MAX ? 0 : result;//如果一直没赋值就赋值为0,赋值过就返回result
}
};
点击查看代码
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0,length = 0,sum = 0,result = INT32_MAX;
for(int j = 0;j < nums.size();j++){
sum += nums[j];
while(sum >= target){
length = j - i + 1;
result = result < length ? result : length;
sum -= nums[i++];
}
}
return result == INT32_MAX ? 0 : result;
}
};
** 59.螺旋矩阵II**
leetcode链接:https://leetcode.cn/problems/spiral-matrix-ii/
题目描述:给定一个正整数 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>> res(n,vector<int>(n,0));
int startX = 0,startY = 0,count = 1,offset = 1;//xy为起始位置,count为赋值,offset为遍历长度
int loop = n/2;//遍历次数
int mid = n/2;//中间位置赋值
int i,j;//循环判断
while(loop--){
i = startX;
j = startY;
//从左至右赋值
for(j; j < n-offset; j++){
res[i][j] = count++;
}
//从上至下
for(i; i < n-offset; i++){
res[i][j] = count++;
}
//下行从右向左
for(; j > startX; j--){
res[i][j] = count++;
}
//下至上
for(; i > startY; i--){
res[i][j] = count++;
}
startX++;
startY++;
offset++;
}
//单独处理中间的数
if(n%2 != 0){
res[mid][mid] = count;
}
return res;
}
};
点击查看代码
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n,a,b,target,sum = 0;
cin>>n;
vector<int> res(n);
vector<int> p(n);
for(int i = 0; i<n; i++){
scanf("%d",&res[i]);//数据量大时,scanf和printf更快
sum += res[i];
p[i] += sum;
}
while(~scanf("%d %d",&a,&b)){//前面加~是持续读取
if(a==0)target = p[b];
else{
target = p[b] - p[a-1];
}
printf("%d\n",target);
}
}
开发商购买土地
leetcode链接:https://kamacoder.com/problempage.php?pid=1044
题目描述:在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。
现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。
然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。
注意:区块不可再分。
核心思路:前缀和
点击查看代码
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main(){
int n,m,sum=0,xSum=0,ySum=0;
cin>>n>>m;
vector<vector<int>> res(n,vector<int>(m,0));
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin>>res[i][j];
sum += res[i][j];//记录所有土地的和
}
}
//计算横向和
vector<int> xLine(n,0);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
xLine[i] += res[i][j];
}
}
//计算纵向和
vector<int> yLine(m,0);
for(int j=0; j<m; j++){
for(int i=0; i<n; i++){
yLine[j] += res[i][j];
}
}
int result = INT32_MAX;
//循环划分横向区域
int xCut = 0;
for(int i=0; i<n; i++){
xCut += xLine[i];
result = min(result,abs(sum - xCut - xCut));
}
//循环划分纵向区域
int yCut = 0;
for(int i=0; i<m; i++){
yCut += yLine[i];
result = min(result,abs(sum - yCut - yCut));
}
cout<<result<<endl;
}