977题目链接:977. 有序数组的平方 - 力扣(Leetcode)
思路:审一遍题后发现复杂度要求不高,先暴力过一遍题,重构数组然后sort,复杂度在O(nlogn).
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int size=nums.size();
for(int i=0;i<size;i++){
nums[i]*=nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
};
题目进阶要求O(n)的复杂度,我想到一个平方后从中间开始双指针向两边走,但这样还要先找到中间的边界。讲解视频中讲到观察数组的特征可知,大数分布在数组两侧,可以由外向内进行寻找,然后从后向前构建新数组。代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int size=nums.size();
vector<int>result=nums; //保证size相同
int k=size-1; //从后向前更新数组
for(int i=0,j=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;
}
};
209题目链接:209. 长度最小的子数组 - 力扣(Leetcode)
思路: 读题首先想到暴力算法双循环O(n²),查看数据量后作罢。双循环减低复杂度联想到双指针,但具体运动方式没有思路。查看文章讲解后学习到了滑动窗口。表达长度最小的子数组需要两个下标,一个表示数组头,一个表示数组尾。在只保留数组尾的情况下,通过滑动窗口是可以表达出数组头的。并且每个元素只被操作2次,复杂度为O(n).
代码如下:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum=0;
int length=0;
int result=INT32_MAX;
int size=nums.size();
for(int i=0,j=0;j<size;j++){
sum+=nums[j];
while(sum>=target){
length=j-i+1;
sum-=nums[i];
i++;
result=min(length,result);
}
}
return result==INT32_MAX?0:result;
}
};
59题目链接:59. 螺旋矩阵 II - 力扣(Leetcode)
大模拟,不附代码了,慢慢写就写出来了。