LeetCode 977 有序数组的平方
题目链接:704.有序数组的平方
题目要求:给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按照非递减顺序排序。
题目分析:“非递减顺序”排序的整数数组,数组中含有负数,该整数数组平方后的值,两边高,中间低。解法一:将数组中的每个值平方,然后对新数组排序即可,时间复杂度为O(n+nlogn)。解法二:利用头指针和尾指针,分别指向数组头和尾,然后依次头元素和尾元素平方的大小,将大的值保存在新数组尾部,然后滑动头指针和尾指针,时间复杂度为O(n)。
解法一:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i = 0; i < nums.size(); i++) {
nums[i] *= nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
解法二:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result (nums.size(), 0);
int i = 0, j = nums.size() - 1, k = nums.size() - 1;
while(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;
}
};
LeetCode 209 长度最小的子数组
题目链接:209.长度最小的子数组
题目要求:给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回0。
题目分析:该题的解法较多,可以嵌套循环暴力枚举出以每个元素开头符合要求的子数组,时间复杂度为O();另一种解法,通过快和慢的双指针控制一个滑动窗口,先移动fast指针,直到窗口内的元素总和符合要求,记录此时的窗口长度为子数组长度;然后,移动slow指针,判定窗口内元素综合和target之间的关系,并继续移动slow指针,小于则移动fast指针。在上述过程中,同步更新子数组长度,选取最小的窗口长度作为子数组长度。循环往复,直到fast指针走到最后。
暴力解法:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum;
int subLength = 0;
int minLength = INT_MAX;
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;
minLength = minLength < subLength ? minLength : subLength;
break;
}
}
}
return minLength == INT_MAX ? 0 : minLength;
}
};
快慢指针:可以实现为双循环控制和单循环控制,双循环逻辑思清晰,单循环稍有复杂。
class Solution { \\双循环
public:
int minSubArrayLen(int target, vector<int>& nums) {
int minLength = INT32_MAX, subLength;
int sum = 0;
int slow = 0, fast = 0;
while(fast < nums.size()) { \\双循环,外层循环控制快指针,计算窗口内元素总和num
sum += nums[fast++];
while(sum >= target) { \\当sum大于target时,计算subLength,并移动慢指针
subLength = fast - slow;
minLength = minLength < subLength ? minLength : subLength;
sum -= nums[slow++];
}
}
return minLength == INT32_MAX ? 0 : minLength;
}
};
class Solution { \\单循环
public:
int minSubArrayLen(int target, vector<int>& nums) {
int minLength = INT32_MAX, subLength;
int sum = 0;
int slow = 0, fast = 0;
while(fast < nums.size() || sum >= target) { \\单循环控制,fast不能超过数组长,特殊情况,fast过界,但是因为else操作的是上次fast的状态,所以也应该进入循环
if(sum < target) {
sum += nums[fast++];
}else{
subLength = fast - slow; \\else操作的是上次fast的状态,所以subLength不加1
minLength = minLength < subLength ? minLength : subLength;
sum -= nums[slow++];
}
}
return minLength == INT_MAX ? 0 : minLength;
}
};
LeetCode 59 螺旋矩阵Ⅱ
题目连接:59.螺旋矩阵Ⅱ
题目要求:给你一个正整数,生成一个包含1到所有元素,且元素按照顺时针螺旋排列的正方形矩阵matrix,如图所示。
题目分析:该题思想不难,难点在于控制边界条件,顺时针转圈赋值。这里约定每次沿着边长的赋值步长为该行(列)的第一个元素~该行(列)的倒数第二个元素,行(列)的最后一个元素作为下一次步长的起点,正方形有四个边,所以转一次圈需要走四次;每次转弯一圈,沿着矩阵对角线顺序,更新下一次的起点;第一圈的步长为,第二圈的步长为,以此类推,共转圈,第的步长为。这里存在一个问题,如果为偶数,则转完圈,矩阵的每个元素都被赋值,如果为为奇数,则矩阵正中间的值空缺,此时应该手动赋值。实现如下。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int startx = 0, starty = 0;
int count = 1;
int offset = 1;
int loop = n / 2 ;
while(loop--) {
int i = startx, j = starty;
for(; j < n - offset; j++) {
res[i][j] = count++;
}
for(; i < n - offset; i++) {
res[i][j] = count++;
}
for(; j > starty; j--) {
res[i][j] = count++;
}
for(; i > startx; i--) {
res[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if(n % 2){
res[n / 2][n / 2] = count;
}
return res;
}
};
数组内容的总结,数组作为基础的数据结构,主要考察对于代码的掌控能力,要熟记数组结构的特点,数组下标从0开始,数组存储空间连续,可以随机存取,数组元素只能覆盖,不能删除,数组定长,等。