977.有序数组的平方
题目建议: 本题关键在于理解双指针思想
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
暴力解,没啥好说的
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int fast = 0; fast < nums.size(); fast++){
nums[fast] = nums[fast] * nums[fast];
}
sort(nums.begin(),nums.end());
return nums;
}
};
双指针解法
用空间换时间
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[i] * nums[i];
k--;
i++;
}else{
result[k] = nums[j] * nums[j];
k--;
j--;
}
}
return result;
}
};
文章讲解:代码随想录
视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili
209.长度最小的子数组
题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议大家先看视频讲解。 拓展题目可以先不做。
自己思路是暴力解,但是边界条件未能解决,数组越界访问报错好几次,反复修改。
我的想法是两层for循环,外层确定起始位置,内层逐个元素相加,与target值进行比较,用count计数,sum超过target时将count存入新定义数组中,最后遍历数组,寻找最小值。
至于返回0条件需要单独判断。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
//暴力解
int n = nums.size();
vector<int> A(n, 0); // 使用vector代替数组,并初始化为0
int x = 0;
for(int i = 0; i < n; i++){
int sum = 0;
int count = 0;
for(int j = i; j < n; j++){
sum = sum + nums[j];
count++;
if(sum >= target){
if(x < n){
A[x] = count;
x++;
}else{
break;
}
}
}
}
bool B = true;
for (int i = 0; i < x; i++) {
if (nums[i] != 0) {
B = false;
break;
}
}
if(B == true){
return 0;
}
for(int i = 0; i < x - 1; i++){
if(A[i] < A[i + 1]){
A[i + 1] = A[i];
}
}
return A[x-1];
}
};
carl哥暴力解两层for循环,只记录最小count值
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum;
int result = INT32_MAX;//最终结果
int subLength = 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){
subLength = j - i + 1;//获取相邻数组长度
result = result < subLength ? result : subLength;
break;//为啥要加break
}
}
}
//不存在符合条件的数组
if(result == INT32_MAX){
return 0;
}
return result;
}
};
滑动窗口解法:
首先j来记录结束位置,i记录起始位置,当相邻元素和符合条件时,删去起始位置元素。
然后移动起始位置
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;
int subLength = 0;//记录子数组长度
int result = INT32_MAX;//记录最终结果
int i = 0;//记录起始位置
for(int j = 0; j < nums.size(); j++){
sum += nums[j];
while(sum >= target){
subLength = j - i + 1;
result = result < subLength ? result : subLength;
sum -= nums[i];
i++;
}
}
if(result == INT32_MAX){
return 0;
}else{
return result;
}
}
};
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文章讲解:代码随想录
视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili
59.螺旋矩阵II
题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
左闭右开是关键
首先要考虑数组方阵行列是否为偶数,当为奇数时,循环到最后还留有最中心的元素
我觉得最妙的变量是offset,这个变量解决了每次开区间的尽头问题
循环的主体不变,因此全程保持一致性,那么如何从个性中找到共性,要学会找相同的处理方法。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
//第一行顺序输入,第n列顺序输入,第n行逆序输入,第一列逆序输入,接着将第二行第二个元素接着进行
//左闭右开
//二维数组写法 vector<vector<int>> res(n, vector<int>(n, 0));
vector<vector<int>> cyc( n, vector<int>(n,0));
int x = 0, y = 0;//起始位置
int offset = 1;//控制右开区间
int mid = n / 2;
int i,j;
int count = 1;
while(mid--){
i = x;
j = y;
for(j; j < n - offset; j++){//第一行
cyc[i][j] = count;
count++;
}
for(i; i < n - offset; i++){//末尾一列
cyc[i][j] = count;
count++;
}
for(j; j > x; j--){
cyc[i][j] = count;
count++;
}
for(i; i > y; i--){
cyc[i][j] = count;
count++;
}
x++;
y++;
offset += 1;
}
//n为奇数单独对中心元素赋值
if(n % 2 != 0){
cyc[n/2][n/2] = count;
}
return cyc;
}
};
文章讲解:代码随想录