算法随想Day2【数组】| LC977-有序数组的平方、LC209-长度最小的子数组、LC59-螺旋矩阵Ⅱ
LC977. 有序数组的平方
有了昨天刷题的总结和思考,根据:
-
条件left <= right,总与右边界right = numsize - 1,nums[right]成对
-
条件left < right,总与右边界right = numsize,nums[right - 1]成对
比较轻松地解决了容易出错的边界问题
vector<int> sortedSquares(vector<int>& nums)
{
int left = 0;
int size = nums.size();
int right = size;
int left_square = 0, right_square = 0;
vector<int> array(size); //size个元素的vector容器
while (left < right)
{
left_square = nums[left] * nums[left];
right_square = nums[right] * nums[right];
if (left_square > right_square)
{
array[size - 1] = left_square;
left++;
}
else
{
array[size - 1] = right_square;
right--;
}
size--;
}
return array;
}
LC209. 长度最小的子数组
开始自己的写法,类似于暴力解法,只不过第二层用了while来表示
////力扣上会超出时间限制
int minSubArrayLen_self(int target, vector<int>& nums)
{
int size = nums.size();
int left = 0, right = 0;
int minlen = size, len_count = 0, val_sum = 0;
for (; left < size; left++)
{
len_count = 0;
right = left;
val_sum = nums[left];
while (val_sum < target)
{
right++;
if (right >= size)
{
break;
}
val_sum += nums[right];
len_count++;
}
len_count++;
if (val_sum >= target)
{
minlen = len_count < minlen ? len_count : minlen;
}
if (val_sum < target && len_count == size)
{
return 0;
}
}
return minlen;
}
滑动窗口(双指针)
使用一个for循环完成两个for循环完成的工作,for中的递增变量i应该被视为滑动窗口的终止位置,即end。因为如果视其为起始位置,逐个向后移动,其实跟暴力解法没什么区别。
int minSubArrayLen_slice(int target, vector<int>& nums)
{
int size = nums.size();
int start = 0, end = 0;
int minlen = __INT32_MAX__, len_count = 0, val_sum = 0;
for (; end < size; end++)
{
val_sum += nums[end]; //搜集滑动窗口里的和
////一旦和超过target,记录当前长度,左边界缩小
while (val_sum >= target) //使用while是因为左边起始位置可能不仅只移动一位
{
len_count = end - start + 1;
minlen = len_count < minlen ? len_count : minlen;
val_sum = val_sum - nums[start];
start++;
}
}
return minlen == __INT32_MAX__ ? 0 : minlen;
}

相关题目推荐
LC59. 螺旋矩阵Ⅱ
没有思路,看Carl讲解。
重点是处理边界条件,坚持“循环不变量”,即像二分法每次分数组都要保持“左闭右闭”或“左闭右开”的原则。
- 左闭右开
坚持原则:处理一条边的第一个节点,最后一个节点留给下一条边遍历的时候再做处理。
表达一个坐标的数学式为(i,j)。
起始位置:因为每一圈的起始位置都是会改变的,所以for循环中的i和j在循环中就不会是固定的一个值。所以需要在循环外定义一个startx和starty来表示每次循环的起始位置。
终止位置:也是随着每一圈不断地去改变的,每转一圈,终止位置也应该减1,所以需要多一个变量offset来控制它每次循环的终止位置。
对于n * n的一个矩阵,需要转圈赋值的圈数为n / 2圈,若n为奇数,需要最后对矩阵的中心进行单独赋值。
class Solution
{
public:
/*
—— —— → y轴(j)
|
|
↓
x轴(i) */
vector<vector<int>> generateMatrix(int n)
{
int i = 0, j = 0;
int startx = 0, starty = 0;
int loop = n / 2, count = 1;
int mid = n / 2;
int offset = 1;
vector<vector<int>> array(n, vector<int>(n, 0)); //使用vector定义一个二维数组并初始化为0
////左闭右开原则
while (loop--)
{
////每一圈的起始位置会改变,用startx表示
for (j = starty; j < n - offset; j++)
{
array[startx][j] = count++;
}
for (i = startx; i < n - offset; i++) //此时j已经等于n - 1
{
array[i][j] = count++;
}
for (; j > starty; j--)
{
array[i][j] = count++;
}
for (; i > startx; i--)
{
array[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if (n % 2 == 1)
{
array[mid][mid] = count;
}
return array;
}
};
类似题目
- 54.螺旋矩阵
- 剑指Offer 29.顺时针打印矩阵

浙公网安备 33010602011771号