代码随想录算法训练营第二天| 977.有序数组的平方、209.长度最小的子数组(904.水果成篮)、59.螺旋矩阵II
977.有序数组的平方
【题目描述】
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
【思路】
昨天刷过了,今天再刷一遍
双指针法,分别指向头start和尾end的位置。比较头和尾的元素j绝对值大小,将大的元素插入进新数组result的尾部。当while(start <= end)结束,返回新数组result。
因为数组不能使用头插法,所以只能创建和原数组一样的大小,从后往前插入元素。
代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int start = 0;
int end = nums.size() - 1;
vector<int> result(nums.size());
int n = nums.size() - 1;
while(start <= end){
if(abs(nums[start]) > abs(nums[end])){
result[n] = nums[start] * nums[start];
++start;
--n;
}
else{
result[n] = nums[end] * nums[end];
--end;
--n;
}
}
return result;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
209.长度最小的子数组
【题目描述】
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
【思路】
1、暴力解
2、滑动窗口(忘记了)
错误暴力解法:
写成了计算子数组个数的解法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = 0;
for(int i = 0;i != nums.size() - 1 ;++i){
int sum = nums[i];
for(int j = i + 1 ;j != nums.size();++j){
if(sum + nums[j] < target){
sum += nums[j];
}
else if(sum + nums[j] > target){
continue;
}
else{
++result;
}
}
if(nums[nums.size() - 1] == target){
++result;
}
}
return result;
}
};
时间复杂度:O(n^2)
空间复杂度:O(1)
暴力解法:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = nums.size();
int subLenght = 0;
for(int i = 0;i != nums.size() ;++i){
int sum = 0;
for(int j = i ;j != nums.size();++j){
sum += nums[j]; //因为都是正整数,所以一直加就好了
if(sum >= target){
subLenght = j - i + 1;
result = result > subLenght ? subLenght : result;
break; //一找到符合条件就退出当前循环
}
}
}
return result == nums.size() ? 0 : result; //如果没有修改值就返回0
}
};
时间复杂度:O(n^2)
空间复杂度:O(1)
滑动窗口解法:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = nums.size() + 1; //取大于nums数组大小的值
int sum = 0; //滑动窗口大小
int subLenght = 0; //连续子数组的长度
int start = 0; //头指针
for(int end = 0;end != nums.size();++end){ //移动尾指针
sum += nums[end]; //更新滑动窗口,因为数组中都是正整数,所以可以一直加
//注意:这里是while循环。当连续子数组的和大于target才进入循环修改result数据
while(sum >= target){
subLenght = end - start + 1; //当前连续子数组的长度
result = result > subLenght ? subLenght : result;//更新最小连续子数组的长度
sum -= nums[start++]; //缩小滑动窗口的大小,直到小于target才退出循环
}
}
return result == nums.size() + 1 ? 0 : result;//如果最小连续子数组长度没有改变就返回0
}
};
时间复杂度:O(n)
空间复杂度:O(1)
904.水果成篮
【题目描述】
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。
【思路】
不会,思路参考leetcode官方答案
滑动窗口解法:
使用哈希表当做篮子,当使用的篮子个数大于2时,清除start指针所指元素。
滑动窗口解法:
class Solution {
public:
int totalFruit(vector<int>& fruits) {
unordered_map<int,int> basket; //使用的篮子
int result = 0; //篮子中水果个数
int start = 0;
for(int end = 0;end != fruits.size();++end){
++basket[fruits[end]]; //如果哈希表中没有此种类水果,下标操作会直接插入此种类
while(basket.size() > 2){
--basket[fruits[start]]; //将哈希表中此种类水果个数减一,直到元素个数为0时,删除此种类
if(basket[fruits[start]] == 0){
basket.erase(fruits[start]);
}
++start;
}
result = max(result , end - start + 1); //每次循环都检查当前水果个数是不是比之前多
}
return result;
}
};
时间复杂度:O(n)
空间复杂度:O(1)
59.螺旋矩阵II
【题目描述】
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
【思路】
二刷还是不能AC出来
1、设置开始位置(0,0)
2、设置圈数 (忘记)
3、设置偏移量(忘记)
4、设置需要赋值的值
5、判断n是否为奇数,如果是的话在矩阵最中间赋值
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n,vector<int>(n)); //最终的正方形矩阵
int startX = 0,startY = 0; //循环起始位置(0,0)
int num = 1; //要赋值的数
int count = n / 2; //循环总圈数
int offset = 1; //每一圈的偏移量
while(count > 0){
for(;startX < n - offset ; ++startX){
result[startY][startX] = num++;
}
for(;startY < n - offset;++startY){
result[startY][startX] = num++;
}
for(;startX > offset - 1;--startX){
result[startY][startX] = num++;
}
for(;startY > offset - 1;--startY){
result[startY][startX] = num++;
}
++startX;
++startY;
++offset;
--count;
}
if(n % 2 != 0){ //如果n为奇数的话,为最中间的位置赋值
result[n/2][n/2] = num;
}
return result;
}
};
时间复杂度:O(n^2)
空间复杂度:O(1)