977.有序数组的平方
题目描述:给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
暴力解法:分两个小步,第一小步:把原来每个数组元素都变成自己本身的平方,第二小步:再对处理好的数据进行排序处理。
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
for (int i = 0; i < A.size(); i++) {
A[i] *= A[i];
}
sort(A.begin(), A.end()); // 快速排序
return A;
}
};
双指针解法:已知给定的数组是有序的,且可能包含负数,假设不包含负数,那么最大值只可能在数组末尾出现,假设包含负数,那么最大值可能在开头,也可能在末尾,两种情况唯独不可能出现在中间,“中庸”现象。双指针的思路就是:一个指针指头部元素平方,一个指针指尾部元素平方,二者取其大者,从新数组的尾部开始插入然后那个大者的指针继续移动,小的不做改变。
int* sortedSquares(int* nums, int numsSize, int* returnSize){
//返回的数组大小就是原数组大小
*returnSize = numsSize;
//创建两个指针,right指向数组最后一位元素,left指向数组第一位元素
int right = numsSize - 1;
int left = 0;
//最后要返回的结果数组
int* ans = (int*)malloc(sizeof(int) * numsSize);
int index;
for(index = numsSize - 1; index >= 0; index--) {
//左指针指向元素的平方
int lSquare = nums[left] * nums[left];
//右指针指向元素的平方
int rSquare = nums[right] * nums[right];
//若左指针指向元素平方比右指针指向元素平方大,将左指针指向元素平方放入结果数组。左指针右移一位
if(lSquare > rSquare) {
ans[index] = lSquare;
left++;
}
//若右指针指向元素平方比左指针指向元素平方大,将右指针指向元素平方放入结果数组。右指针左移一位
else {
ans[index] = rSquare;
right--;
}
}
//返回结果数组
return ans;
}
209.长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其和 ≥ target
的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
暴力解法:用两个for解题目:第一个for确认数组起点,第二个for确认数组终止位置,思路不难理解,其中的细节值得扣一扣。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX; // 最终的结果
int sum = 0; // 子序列的数值之和
int subLength = 0; // 子序列的长度
for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
sum = 0;
for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
sum += nums[j];
if (sum >= s) { // 一旦发现子序列和超过了s,更新result
subLength = j - i + 1; // 取子序列的长度
result = result < subLength ? result : subLength;
break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
}
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
滑动窗口解法:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。 实际上滑动窗口也算是双指针解法的一种,但是想一个窗口一样,所以叫滑动窗口。可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。
int minSubArrayLen(int target, int* nums, int numsSize){
//初始化最小长度为INT_MAX
int minLength = INT_MAX;
int sum = 0;
int left = 0, right = 0;
//右边界向右扩展
for(; right < numsSize; ++right) {
sum += nums[right];
//当sum的值大于等于target时,保存长度,并且收缩左边界
while(sum >= target) {
int subLength = right - left + 1;
minLength = minLength < subLength ? minLength : subLength;
sum -= nums[left++];
}
}
//若minLength不为INT_MAX,则返回minLnegth
return minLength == INT_MAX ? 0 : minLength;
}
59.螺旋矩阵II
给你一个正整数 n
,生成一个包含 1
到 n^2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
解决螺旋矩阵的主要方法就是对条件进行判断,我们要保持条件判断的一致性,模拟顺时针画矩阵的过程:上行从左到右,右行从上到下,下行从右到左,左行从下到上。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
*returnSize=n;
*returnColumnSizes=(int *)malloc(sizeof(int)*n);
int **ans=(int**)malloc(sizeof(int*)*n);
int i;
for(i=0;i<n;i++){
ans[i]=(int*)malloc(sizeof(int)*n);
(*returnColumnSizes)[i]=n;
}
int starX=0;
int starY=0;
int mid=n/2;
int loop=n/2;
int offset=1;
int count=1;
while(loop){
int i=starX;
int j=starY;
for(;j<starY+n-offset;j++){
ans[starX][j]=count++;
}
for(;i<starX+n-offset;i++){
ans[i][j]=count++;
}
for(;j>starY;j--){
ans[i][j]=count++;
}
for(;i>starY;i--){
ans[i][j]=count++;
}
offset+=2;
starX+=1;
starY+=1;
loop--;
}
if(n%2)
ans[mid][mid]=count;
return ans;
}
其中需要注意的是对边界条件的判断,还有如果n是奇数,中间就有一个单独的空缺,要单独拿出来判断