第一题-977.有序数组的平方
自己尝试
看到这道题,我的第一个想法便是直接遍历原数组平方,再给新数组排序(冒泡排序)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int len = nums.size();//原数组大小
for (int i = 0; i < len; i++) {
nums[i] = nums[i] * nums[i];//得到平方后的新数组
}
//冒泡排序得到新数组
for (int j = len-1; j >=0;j--) {
for (int i = 0; i < j; i++) {
//如果前一个数大于后一个数,交换位置
if (nums[i] > nums[i + 1]) {
int change;
change = nums[i];
nums[i] = nums[i + 1];
nums[i + 1] = change;
}
}
}
return nums;
}
};
成功解决问题,但执行时间比较长
这里整理一下内部排序的时间复杂度:
- O(nlogn): 快速排序、堆排序和归并排序
- O(n^2): 直接插入排序、冒泡泡排序和简单选择排序
- O(n): 基数排序
根据视频解答-双指针法
使用双指针法,由于原始的数组是非递减的,因此只需要比较负数的平方和正数的平方大小,更改顺序即可,即数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。可以考虑双指针法了,i指向起始位置,j指向终止位置。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> new_nums(nums.size(),0);
int k = nums.size() - 1;//用于从后往前存新数组
int i, j;//双指针 i-从前往后,j-从后往前
//循环条件需要i=j,否则缺失nums[i]=nums[j]的这个元素
for (i = 0, j = nums.size()-1; i <= j;){
//左边的平方比右边的平方大
if (nums[i] * nums[i] > nums[j] * nums[j]) {
new_nums[k] = nums[i] * nums[i];
i++;
k--;
}
//右边的平方比左边的平方大或相等
else {
new_nums[k] = nums[j] * nums[j];
j--;
k--;
}
}
return new_nums;
}
};
出现的问题:
原因:没有初始化新数组new_nums,增加语句vector<int> new_nums(nums.size(),0);
第二题-209.长度最小的子数组
自己尝试
我的想法是先对数组由大到小排序,再从前往后相加数组的每一个值,并设置一个计数器,s直到总和大于或等于target,输出计数器的值,如果整个数组的和都小于target则输出0
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
//降序排序
sort(nums.rbegin(), nums.rend());
int total = 0;
for (int i = 0; i < nums.size(); i++) {
total = total + nums[i];
if (total >= target) {
return i + 1;
}
}
return 0;
}
};
问题:没有考虑到题目中要求“长度最小的 连续子数组 ”,这样求出来的未必连续,因此有些测试用例没有通过
根据视频解答-滑动窗口
【滑块移动】遍历终止位置,找到第一个满足条件的数组元素个数,进入循环,如果一直满足条件则起始位置往后移动,如果不满足条件则终止位置往后移动,找到最少的个数
- 注意,此处result起始取一个较大的值,便于后续比较寻找最小的值
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0, total=0,result=1000000;//起始位置
//j是终止位置
for (int j = i; j < nums.size(); j++) {
//从起始位置加
total = total + nums[j];
while(total >= target) {
if (j - i + 1 < result) {
result = j - i + 1;
}
//此时符合条件,移动起始位置
total = total - nums[i];
i++;
}
}
if (result == 1000000)return 0;
return result;
}
};
第三题-59.螺旋矩阵II
根据视频解答
重点:左闭右开,其实内容不难,就是比较麻烦,好早最后都解决了!画了一个简略图如下,可以方便理解
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> num(n, vector<int>(n));
int count = 1;
int startx=0, starty=0;
int len = n;
if (n == 1) {
return { {1} };
}
//绕n/2圈
for (int quan = 0; quan <len / 2; quan++) {
//第一行除了最后一个元素
for (int i = starty; i < n - 1; i++) {
num[startx][i] = count;
count++;
}
//最右一列除了最后一个元素
for (int i = startx; i < n - 1;i++) {
num[i][n - 1] = count;
count++;
}
//最后一行除了最后一个元素
for (int i = n - 1; i > starty; i--) {
num[n - 1][i] = count;
count++;
}
//第一列除了最后一个元素
for (int i = n - 1; i >startx; i--) {
num[i][starty] = count;
count++;
}
startx++;
starty++;
n = n - 1;
}
//n为奇数
if (len % 2 != 0) {
num[len / 2][len / 2] = count;
}
return num;
}
};