前言
第二天打卡!
一、有序数组的平方
昨天进行拓展联系已经完成该题目。
二、长度最小的子数组
1.错误代码
根据自己思路,每次从i开始,计算往后首次满足和大于目标值的子数组长度,时间计算超时。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int slowIndex = 0;
int len = nums.size() + 1;
for(;slowIndex < nums.size();slowIndex++){
if(nums[slowIndex] == target){
return 1;
}
int sum = nums[slowIndex];
int fastIndex = slowIndex + 1;
while(fastIndex < nums.size() && sum < target ){
sum += nums[fastIndex++];
}
if(sum >= target){
if(fastIndex - slowIndex < len){
len = fastIndex - slowIndex;
}
}
}
if(len <= nums.size()){
return len;
}else{
return 0;
}
}
};
2.正确题解
根据滑动窗口,快指针向前滑动至 和大于目标值,慢指针开始滑动,滑动至 和小于目标值,快慢指针交替滑动,时间复杂度O(n).
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0;
int sum = 0;
int subLength = 0;
int len = INT32_MAX;
for(int j = 0; j < nums.size();j++){
sum += nums[j];
while(sum >= target){
subLength = (j - i + 1);
len = len < subLength ? len : subLength;
sum -= nums[i++];
}
}
return len == INT32_MAX ? 0 : len;
}
};
但是慢指针向前滑动的过程中,每次都计算长度并比较,能否改进成while结束执行一次。
3.改进
根据朋友交流,选择了flag标志方法,但实际执行过程中,每次都会判断flag,速度提升不明显,可能部分情况存在负提升。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0;
int sum = 0;
int subLength = 0;
int len = INT32_MAX;
int flag = 0;
for(int j = 0; j < nums.size();j++){
sum += nums[j];
while(sum >= target){
sum -= nums[i++];
flag = 1;
}
if(flag == 1){
subLength = (j - i + 2);
len = len < subLength ? len : subLength;
flag = 0;
}
}
return len == INT32_MAX ? 0 : len;
}
};
4.练习
水果成篮
使用了map完成哈希存储
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int left = 0;
int ans = 0;
unordered_map<int, int> cnt;
for(int right = 0;right < fruits.size();right++){
++cnt[fruits[right]];
while(cnt.size() > 2){
--cnt[fruits[left]];
if(cnt[fruits[left]] == 0){
cnt.erase(fruits[left]);
}
++left;
}
ans = max(ans,right - left + 1);
}
return ans;
}
};
三、螺旋矩阵
1.题解
利用模拟,不断由外,一层层向内,注意边界问题。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int t = 0; //top
int b = n - 1; //bottom
int l = 0; //left
int r = n - 1; //right
vector<vector<int>> ans(n, vector<int>(n));
int k = 1;
while(k <= n * n){
for(int i = l; i <= r; i++,k++) ans[t][i] = k;
t++;
for(int i = t; i <= b; i++,k++) ans[i][r] = k;
r--;
for(int i = r; i >= l; i--,k++) ans[b][i] = k;
b--;
for(int i = b; i >= t; i--,k++) ans[i][l] = k;
l++;
}
return ans;
}
};
2.练习
由于矩阵不规则,每个for均需要进行判断,否则k可能越界。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
int t = 0;
int b = m - 1;
int l = 0;
int r = n - 1;
int k = 0;
vector<int> ans(m * n);
while(k < m * n){
for(int i = l;i <= r && k <m * n; i++, k++) ans[k] = matrix[t][i];//printf("a%d\n",k);
t++;
for(int i = t;i <= b && k <m * n; i++, k++) ans[k] = matrix[i][r];//printf("b%d\n",k);
r--;
for(int i = r;i >= l && k <m * n; i--, k++) ans[k] = matrix[b][i];//printf("c%d\n",k);
b--;
for(int i = b;i >= t && k <m * n; i--, k++) ans[k] = matrix[i][l];//printf("d%d\n",k);
l++;
}
return ans;
}
};
总结
根据两天数组相关题目的练习,针对数组的操作,个人认为边界是最关键的,把握好边界以防造成越界错误。