提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、LeetCode:977.有序数组的平方
<1> 暴力解法:
思路:
将原数组内的每个元素取平方放到新数组内,然后排序,最后返回。
代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> arr;
int j = 0;
int size = nums.size();
for(int i = 0; i<size; i++)
{
j = pow((abs(nums[i])),2);
arr.push_back(j);
}
sort(arr.begin(), arr.end());
return arr;
}
};
时间复杂度:O(N logN)
空间复杂度:O(N)
<2> 双指针法:
思路:
注意:无论是否有负数,平方后的最大值一定位于原有序数组的两边,而非中间,所以设置两个指针,从两边向中间遍历比较平方大小即可。
代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int size = nums.size()-1;
vector<int> result(size+1);
for(int i=0,j=size;i<=j;)
{
if((nums[i]*nums[i])>(nums[j]*nums[j])){
result[size--] = (nums[i]*nums[i]);
i++;
}else{
result[size--] = (nums[j]*nums[j]);
j--;
}
}
return result;
}
};
时间复杂度:O(N)
空间复杂度:O(N)
二、LeetCode:209.长度最小的子数组
<1> 暴力解法(会超出时间限制)
思路:
通过2个for循环,遍历出每一种可能性的长度,然后选择其中满足条件的最小长度,就是题目答案。
代码如下(示例):
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = nums.size()+1;
int length = 0;
int sum = 0;
//第一个for循环:遍历每个元素。
for(int i = 0;i<nums.size();i++){ //子序列起点位置i
sum = 0;
//第二个for循环:从每个下标=i的元素开始遍历,找到满足条件的长度。
for(int j = i;j<nums.size();j++){ //子序列终止位置j
sum += nums[j];
if(sum>=target){
length = j-i+1;
result = result<length?result:length;
break;
}
}
}
return result == nums.size()+1?0:result;
}
};
时间复杂度:O(N^2)
空间复杂度:O(1)
<2> 滑动窗口
思路:
1.依旧是双指针的思想:i 指针遍历每一个元素, 而 j 指针记录下每次满足条件时的下标位置。
2.然后通过1个for循环来实现暴力解法中2个for循环的功能。
代码如下:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;//用来不停加,直到满足条件
int subLength = 0;//满足条件时的数组长度
int i = 0;//用来遍历每个元素
int result = nums.size()+1;
for(int j = 0;j<nums.size();j++){
sum += nums[j];
/*下面是while循环而不是if判断,因为需要注意一些特殊情况:
[1,1,1,1,1,100]这种,不能判定一次就结束*/
while(sum >= target){
subLength = j-i+1;
result = min(result, subLength);
sum -= nums[i++];//满足条件就会减去开头元素值,然后i++就会指向下一位元素
}
}
return result == nums.size()+1?0:result;
}
};
时间复杂度:O(N)
空间复杂度:O(1)
三、LeetCode: 59.螺旋矩阵II
思路:
1.注意遵循循环不变量原则,即循环体内部是不会变化的,这就要求我们一定要注意边界条件。
2.注意二维数组的行或者列,我们是可以控制的,要灵活改变。
3.圈数的计算。
代码如下:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
//遵循左闭右开的原则:
vector<vector<int>> res(n,vector<int>(n,0));//建立二维数组
int startX = 0, startY = 0;//X坐标,Y坐标
int loop = n/2;//圈数的计算
int mid = n/2;//螺旋的最中间
int count = 1; //代表二维矩阵中的每格元素值
int offset = 1;//offset控制每一圈里每一条边遍历的长度
int i,j;
while(loop--){
i = startX;
j = startY;
//最上边:从左到右
for(j = startY;j<n-offset;j++){
res[startX][j] = count++;
}
//最右边:从上到下
for(i = startX;i<n-offset;i++){
res[i][j] = count++;
}
//最下边:从右到左
for(;j>startY;j--){
res[i][j] = count++;
}
//最左边:从下到上
for(;i>startX;i--){
res[i][j] = count++;
}
//第增加一圈,各起始位置就要+1
startX++;
startY++;
//offset控制每一圈里每一条边遍历的长度
offset += 1;
}
//如果n为奇数,需要把最中间位置给它
if(n%2){
res[mid][mid] = count;
}
return res;
}
};