有序数组的平方
通过双指针实现,第一指针从数组开头往后面遍历,第二个指针从数组末尾往前面遍历,比较nums[left] ^2与 nums[right]^2的大小,将较大的数字加入到新的数组newnums中。注意遍历条件是left<=right当两个指针相遇时,存入的是nums[left] ^2,因为判断条件是nums[left] * nums[left] <= nums[right] * nums[right]。最后由于数组要求从小到大排序,我们通过algorithm库的reverse函数将首尾反转。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> newnums;
int left=0, right=nums.size()-1;
while (left<=right)
{
if (nums[left] * nums[left] <= nums[right] * nums[right])
{
newnums.push_back(nums[right] * nums[right]);
right--;
}
else
{
newnums.push_back(nums[left] * nums[left]);
left++;
}
}
reverse(newnums.begin(),newnums.end());
return newnums;
}
};
长度最小的子数组
如果不使用双指针算法,两重循环的复杂度是O(n^2) .通过滑动窗口(双指针模板中的一种),第二个指针不用回溯,因此两个指针分别走n趟,因此优化了朴素算法,复杂度是O(n)。
双指针模板:
for(i=0,j=0;j<n;j++)
{
while(i<j&&check(i,j)) i++;//符合每道题的具体check逻辑
}
j-i+1表示当前窗口的长度。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int lowpostion,fastpostion,sum;
int Sublen = INT_MAX;
for (slowpostion = 0, fastpostion = 0,sum=0; fastpostion < nums.size(); fastpostion++)//滑动窗口,用fastpostion表示结束位置,然后不断缩小起始位置,由于起始位置每次都是从上一个起始位置的最后更新值开始更新,因此时间复杂度并不是O(n^2),而是O(n+n);
{
sum += nums[fastpostion];
while (sum >= target)
{
Sublen = Sublen > fastpostion - slowpostion + 1 ? fastpostion - slowpostion + 1 : Sublen;
sum -= nums[slowpostion++];
}
}
return Sublen == INT_MAX ? 0 : Sublen;//如果没有找到,即for循环遍历完都没有进入wihle循环,则返回0
}
};
螺旋矩阵
每一轮循环走最外面的一圈,一共循环n/2次,如果n是奇数,最后还要单独给中心的元素matrix[n/2][n/2]赋值。为了使每一次循环步长相同,从左到右,从上到下,从右到左,从下到上分都移动相同的长度,即left->right-1;top->down-1;right->left+1;down->top-1。
for (int i = top, j = left; j < right; j++)
{
matrix[i][j] = num++;
}
for (int i = top, j = right; i<down; i++)
{
matrix[i][j] = num++;
}
for (int i = down, j = right; j>left; j--)
{
matrix[i][j] = num++;
}
for (int i = down, j = left; i >top; i--)
{
matrix[i][j] = num++;
}
完整代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n));
int left, right, top, down;
int num = 1;
left = 0, right = n - 1, top = 0, down = n - 1;
while (left<right)
{
for (int i = top, j = left; j < right; j++)
{
matrix[i][j] = num++;
}
for (int i = top, j = right; i<down; i++)
{
matrix[i][j] = num++;
}
for (int i = down, j = right; j>left; j--)
{
matrix[i][j] = num++;
}
for (int i = down, j = left; i >top; i--)
{
matrix[i][j] = num++;
}
left++, right--, top++, down--;
}
if (n % 2) matrix[n/2][n/2] = num;
return matrix;
}
};