LC 题目
题目链接:LC 977 有序数组的平方
思路:双指针法,两个指针分别指向数组的头尾,向中间遍历。每次遍历比较数组两数的平方大小,把大的数放在新数组的最后,新数组从后向前遍历。
代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size(), 0);//创建大小为nums.size(),初始值为0的vector
int l = 0;
int r = nums.size()-1;
for(int j=result.size()-1; j>=0; --j){
if(nums[l]*nums[l]>=nums[r]*nums[r]){
result[j] = nums[l]*nums[l];
++l;
}
else{
result[j] = nums[r]*nums[r];
--r;
}
if(l>r)break;
}
return result;
}
};
题目链接:LC 209 长度最小子数组
思路:滑动窗口,窗口的大小是动态的,借用双指针的思想,指针指向窗口的起始和末尾。首先尾指针向后遍历,直到窗口内的值大于等于target,若比之前窗口长度小则记录窗口长度;然后首指针向后遍历,若窗口内的值仍大于等于target且长度小于旧的则记录新长度,若窗口值小于target则后指针向后遍历(重复开始的步骤)。
代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int l = 0;//窗口的开始
int r = 0;//窗口的末尾
int sum = 0;//窗口内的值的总和
int minLen = INT32_MAX;//记录滑动窗口的最小值
int len = 0;//记录滑动窗口的大小
while(r<nums.size()){//当r遍历到数组的最后一个的后面时,跳出循环
sum = sum + nums[r];//从末尾扩大滑动窗口范围
++len;
++r;
while(sum>=target){//当窗口内的值大于等于target时开始从窗口开头收缩窗口
if(minLen>len)minLen = len;//记录最小的窗口长度
sum = sum - nums[l];
++l;
--len;
}
}
minLen = minLen == INT32_MAX ? 0 : minLen;
return minLen;
}
};
题目链接:LC 59 螺旋矩阵||
思路:需要注意两点,第一螺旋矩阵从外往内每一层的每条边的区间(上:左闭右开;右:上闭下开;下:右闭左开;左:下闭上开);第二螺旋矩阵最大边长若为偶数则无需考虑最中心的元素,若为奇数需特殊考虑给中心元素赋值。
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n, vector<int> (n, 0));//定义并初始化返回值
int mid = n/2;//若n为偶数则无用,若n为奇数则矩阵中[mid,mid]位置的值为n*n
int len = n;//每圈的边长
int loop_i = 0;//用来遍历整个矩阵,每一圈的起点坐标,eq[0,0],[1,1]...
int loop_j = 0;
int val = 1;//从1到n*n给矩阵赋值
while(len>1){//边长为1特殊讨论
int i = 0;
int j = 0;
for(;j<len-1;j++){
result[i+loop_i][j+loop_j] = val;
++val;
}
for(;i<len-1;i++){
result[i+loop_i][j+loop_j] = val;
++val;
}
for(;j>0;j--){
result[i+loop_i][j+loop_j] = val;
++val;
}
for(;i>0;i--){
result[i+loop_i][j+loop_j] = val;
++val;
}
loop_i++;
loop_j++;
len = len-2;
}
if(n%2==1)result[mid][mid] = n*n;
return result;
}
};
额外题目
(以上为训练营每日任务,本部分为自己刷题进度)
题目链接:LC 904 水果成篮
思路:滑动窗口,本质上是找到长度最大的滑动窗口,并且滑动窗口内的值只能有两个,可以用map保存窗口中数的种类和个数。首先窗口尾指针向后遍历,当种类大于2时开始收缩窗口(窗口首指针向后遍历),直至满足规则,窗口尾指针继续向后遍历,知道数组最后一个之后。
代码:
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int l = 0;//滑动窗口首指针
int r = 0;//滑动窗口尾指针
unordered_map<int, int> br;//篮子
int max = 0;
while(r<fruits.size()){
++br[fruits[r]];//令尾指针的水果入篮子
while(br.size()>2){//篮子大于两种水果,开始从头指针收缩窗口,同样需要修改map
auto temp = br.find(fruits[l]);
--temp->second;//把篮子中的值-1
if(temp->second == 0) br.erase(temp);
++l;
}
if(max<r-l+1)max = r-l+1;//保存最大长度
++r;//尾指针继续向后遍历
}
return max;
}
};