代码随想录DAY2| 数组 |有序数组的平方977、长度最小的有序数组209、螺旋矩阵59


前言

详细的包含main函数的代码,小白可直接在vs运行~


一、有序数组的平方977

文档&视频讲解:代码随想录

1. 题目

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:非递减序列:前一个数 <= 后一个数

2. 思路

  1. 暴力解法:
    for循环遍历数组,对每个元素平方;
    用sort对数组快速排序。
  2. 双指针:
    提示:因为是非递减序列,平方后的最大值必然在两端
    数组两端取平方比较大小,大者放入 result [k] 最后一位;
    k- -;i++ 或 j- -后 继续比较平方比较大小…

3. 代码实现

暴力解法

//Time:2024/4/17训练营跟练
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	vector<int> sortedSquared(vector<int>& nums) {
		int size = nums.size();
		for (int i = 0; i < size; i++) {
			nums[i] = nums[i] * nums[i];
		}
		//排序
		sort(nums.begin(), nums.end());
		return nums;
	}
};

int main()
{
	vector<int> nums = { -4,-1,0,3,10 };
	Solution solution;
	vector<int> result = solution.sortedSquared(nums);

	cout << "[";
	//result是一个vector,经过for_each遍历之后成为vector里的每个int值
	for_each(nums.begin(), nums.end(), [](int result) {cout << result << " "; });
	cout << "]";

	return 0;
}

双指针

//Time:2024/4/17

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	vector<int> sortedSquared(vector<int>& nums) {
	
		//vector<int> result = { 0 };
		//定义新数组大小和result一样大,且所有元素初始化为0
		vector<int> result(nums.size(), 0);
		int k = nums.size() - 1;

		//注意循环条件:不是 i < nums.size(),而是i<=j
		//for (int i = 0, int j = nums.size() - 1; i <= j ;)错误
		//int类型定义重复
		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];
				//别忘了两个数组的指针都要变化
				k--;
				i++;
			}
			else {
				result[k] = nums[j] * nums[j];
				k--;
				j--;
			}
		}
		return result;
	}
};

int main() 
{

	vector<int> nums = { -7,-3,2,3,11 };
	Solution solution;
	vector<int> result = solution.sortedSquared(nums);

	for_each(result.begin(), result.end(), [](int result) {cout << result << " "; });

	return 0;
}

4.Debug与收获

暴力解法 2024/4/17 一刷

Debug:

  1. 遍历数组时,i<size 不是 i<size-1,(表示数组元素个数时-1)后续还有,代值进去看

收获:

  1. algorithm: sort & for_each
  2. lambda表达式

双指针 2024/4/17 一刷

Debug:

  1. for (int i = 0, int j = nums.size() - 1; i <= j ;)错误
    两个参数的for循环,类型不要定义重复了
  2. 两个数组,数组的指针都要变化;
    i,j变化—>k也要变
  3. 注意循环条件 不是 i < nums.size(),而是i<=j

收获:

  1. 定义新数组的方式:大小和result一样大,且所有元素初始化为0
    // vector result(nums.size(), 0);

二、长度最小的有序数组209

文档&视频讲解:代码随想录

1. 题目

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

提示:

1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5

2. 思路

在这里插入图片描述

提示:
i、j共同构成一个滑动窗口,i、j是nums的索引;
result 是一个判断nums所有元素的和 是否能满足s 的条件;
i的移动条件是sum>=s
j是一直遍历整个数组

提示:INT_MAX 和 INT_MIN 是 C++ 的两个宏,代表了整型变量能够存储的最大正整数和最小负整数,分别为 2147483647 和 -2147483648,这两个宏在头文件 <limits.h> 中定义。

3. 代码实现

//Time:2024/4/17训练营跟练
//
// 变量说明:
// i:窗口起始位置
// j: 窗口结束位置---作为遍历整个数组的索引
// sum: 窗口内元素求和
// subLength: 窗口长度
// result:最终窗口长度

#include<iostream>
#include<vector>
#include<limits.h>

using namespace std;

class Solution {
public:
	int minSubArrayLen(vector<int>& nums, int s) {

		int size = nums.size();
		int sum = 0;
		int i = 0;
		int result = INT32_MAX;
		//int subLength = 0;

		for (int j = 0; j < size; j++) {

			sum += nums[j];
			
			//更新subLength、result、i、sum
			while (sum >= s) {

				//subLength = j - i + 1;
				int subLength = (j - i + 1);
				result = result > subLength ? subLength : result;
				//sum -= nums[i++];//后置++,先对表达式 +,再对变量 +
				sum = sum - nums[i];  
				i++;
			}
		}
		return result = result == INT32_MAX ? 0 : result;
	}
};

int main()
{
	vector<int> nums = { 1,4,4 };
	int s = 4;
	Solution solution;
	int len = solution.minSubArrayLen(nums, s);
	cout << len << endl;

	return 0;
}

4. Debug与收获

双指针

2024/4/18一刷

Debug:

  1. subLength = j - i + 1 ×
    subLength = (j - i + 1) √

  2. sum -= nums[i++]; 后置++的含义,先用原来的i带入运算,再对i++
    (后面一题将会对后置++有更深刻的理解)

收获:
while:只要条件满足,就一直执行循环语句
if:条件满足,执行循环语句,然后就跳出来了

三、螺旋矩阵59

文档&视频讲解:代码随想录

1. 题目

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

输入: 3
输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]

2. 思路

  1. 循环不变量原则,全部左闭右开
    在这里插入图片描述
  2. 先按n为偶数来转圈,最后补充n为奇数时不成圈的最中间元素
  3. 循环中判断i、j是否不变,变的范围,怎么变,循环就很好写
  4. 一圈中,起始位置是不变的,就像拴狗绳钉在那,然后狗绕圈
  5. 一圈结束,开始第二圈前,改变起始位置(startx&starty);同时,循环的范围(n-offset)也要变,两端同时向内收缩,第二圈的雏形就出来了
  6. 注意:count++是先用原始值进行表达式运算,再改变自身,故第一个cout++是count=1,后一个才是赋的coun++:2
  7. 故最后奇数的赋值count++和count均可
    提示:注意:count++是先用原始值进行表达式运算,再改变自身,故第一个cout++是count=1,后一个才是赋的coun++:2
    故最后奇数的赋值count++和count均可

3. 代码实现

//Time:2024/4/18训练营跟练

#include<iostream>
#include<vector>

using namespace std;

class Solution {
public:
	vector<vector<int>> generateMatrix(int n) {

		//形参用引用,这里不是形参
		vector<vector<int>> res(n, vector<int>(n, 0));

		int startx = 0, starty = 0;//定义起始位置的横纵坐标
		int i, j;//定义变化的索引

		int offset = 1;//辅助n,保证左闭右开

		int count = 1;//赋值

		int loop = n / 2;

		int middle = n / 2;

		//先不管n为奇或偶,先循环整圈
		while (loop--) {

			i = startx;// 此时startx和starty均为0,不变;变化的是i、j
			j = starty;

			//开始循环
			//第一行,i不变,j++
			for (j; j < n - offset; j++) {

				//这里cout++是因为赋给的是count=1,后一个才是赋的coun++:2
				res[startx][j] = count++;
				//不行,因为第二圈startx会++
				//res[i][j] = count++;
			}

			//最后一列,j不变,i++
			for (i; i < n - offset; i++) {
				res[i][j] = count++;
			}

			//最后一行,i不变,j--
			//要用startx作为循环变量,为后续第二圈循环做准备
			for (j; j > startx; j--) {
				res[i][j] = count++;
			}

			//第一列,j不变,i--
			for (i; i > starty; i--) {
				res[i][j] = count++;
			}

			startx++;
			starty++;

			offset++; 
			//上述两组自增,使圈两边都缩小了,可以开始第二圈循环
		}

		//若n为奇数,单独为中间不成全的值赋值
		// ?
		//count++是先用表达式赋值,再变量加
		if (n % 2) {
			res[middle][middle] = count++;
		}

		return res;
	}
};

int main() {

	int n = 3;

	Solution solution;
	
	vector<vector<int>> result = solution.generateMatrix(n);

	//用for循环输出数组
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			std::cout << result[i][j] << " ";
		}
		std::cout << std::endl;
	}

	return 0;
}

4. Debug与收获

2024/4/18一刷

收获:

  1. 二维数组的写法

总结

  1. 还好昨天提前写了一题,要不然今天就完不成任务了
  2. 今天看到一篇双非本科上岸的帖子,被激励了,但我确实还有很大差距
  3. 但每天都在进步不是吗?(写思路的时候发现进步好大。。。可能是被后两题折磨出来的
  4. 成长的秘诀可能就是常常少一点放纵吧
  5. 这样写心情总结好羞耻。。。但还挺有意思的
  6. 今天画了一个导图,确实有助于整理思路
  7. 今天写博客时间明显短了很多,果然完事开头难

还需复习
8. 27. 移除元素 暴力解法
9. for_each输出、 lambda 表达式
10. 今天的后两题明天要二刷一下
10.时间复杂度怎么计算。。。

  • 15
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值