977.有序数组的平方
暴力解法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i = 0; i < nums.size(); i ++)
{
nums[i] = nums[i] * nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
直接求平方后排序,使用到了c++ algorithm
库里的快速排序函数 sort()
,平均时间复杂度为O(n*log n),是不稳定的排序
双指针法
i指向数组左端,j指向数组右端,从两端向中间求
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> result(nums.size(),0);
for(int i = 0, j = nums.size() - 1;i <= j;)
{
if(nums[i] * nums[i] < nums[j] *nums[j])
{
result[k--] = nums[j--] * nums[j--];
}
else
{
result[k--] = nums[i--] * nums[i--];
}
}
return result;
}
};
报错,分析得知j或者i减了两次,修改后如下
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> result(nums.size(),0);
for(int i = 0, j = nums.size() - 1;i <= j;)
{
if(nums[i] * nums[i] < nums[j] *nums[j])
{
result[k--] = nums[j] * nums[j];
j--;
}
else
{
result[k] = nums[i] * nums[i];
i++;
}
}
return result;
}
};
209.长度最小的子数组
暴力解法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT_MAX;//初始化最小长度为整数的最大值
int length;
int sum = 0;
for(int i = 0; i < nums.size(); i++)
{
sum = 0;
for(int j = i; j < nums.size(); j++)
{
sum += nums[j];
if(sum >= target)
{
length = j - i + 1;
result = result < length ? result : length;
break;
}
}
}
return result == INT_MAX ? 0 : result;
}
};
时间复杂度为O(n^2),超时
滑动窗口
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT_MAX;
int length;
int sum = 0;
int i = 0;
for(int j = i; j < nums.size(); j++)
{
sum += nums[j];
while(sum >= target)
{
length = j - i + 1;
result = result < length ? result : length;
sum -= nums[i++];// 这里体现出滑动窗口的精髓之处,不断变更i(子序列起始位置)
}
}
return result == INT_MAX ? 0 : result;
}
};
经历报错:while 循环处原本被我用了if循环从而导致报错,分析原因,应该在每次更新 i 后,不断比较子序列是否符合条件,用 if 只会比较一次
使用sum -= nums[i++]
的过程中感受到了算法优化所带来的简洁