1.原题:leetcode977有序数组的平方
【暴力解法】直接循环遍历所有的数组元素,将它们挨个平方,然后再进行升序排列。
源代码如下:
【收获1】对数组进行排序时可以使用sort函数
sort(Array.begin(),Array.end());
【收获2】数组中的push_back()函数的使用方法
vectorans;//定义一个新的容器ans用来储存平方后的数字
for(int i=0;i
完整暴力求解代码:
class Solution {
public:
vector sortedSquares(vector& nums) {
vectorans;
for(int i=0;i
【双指针法求解】
定义左右两个指针i,j分别从数组的左右两端进行移动,每次都移动一位,先计算当前位置的元素的平方,比较当前左右指针所在位置的元素的平方,大的就把它放到result[k],同时k--,让result的倒数下一个位置等待赋值;然后移动被用于赋值的元素位置处的指针,i++或者j--同时另一个指针暂时不动,等待和移动后的指针所指向的元素进行比较。
源代码如下:
class Solution {
public:
vector sortedSquares(vector& nums) {
int k=nums.size()-1;
vectorresult(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];
i++;
}
else
{ result[k--]=nums[j]*nums[j];
j--;
}
}
return result;
}
};
2.原题:leetcode209长度最小的子数组
【暴力求解】写双重循环,第一重找到子序列的起始下标,第二重找子序列的末尾下标,定位一个子数组后就求和,
【收获3】C++中的INT_MAX和INT_MIN是两个预定义宏,代表了整型变量所能存储的最大和最小负整数,分别为2147483647和-2147483648,可以视为int中的无穷大和无穷小
在本题中用到了
int ans = INT_MAX;
return ans == INT_MAX ? 0 : ans;
暴力求解的源代码如下:
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int n = nums.size();
if(n==0) //当数组大小为0时,就直接返回0
{
return 0;
}
int ans = INT_MAX; //定义ans为无穷大的数
for(int i = 0;i= target) //当子数组的和大于或等于给定的target时,就结束查询
{
ans = min(ans,j - i + 1);/*每求一次满足if中条件的一个数组,就对这个所找到的*/
break;
} / * 子数组,就求一次它的区间大小,和上一次找到的进行比较,将最小的最终保存到ans中,跳出内循环*/
}
}
return ans == INT_MAX?0 : ans;//有可能最后ans一直都是初始值INT_MAX在遍历中并没有得到更新。所以要进行最后一次判断,如果没更新过,就表明数组中不存在满足条件的子数组,就让返回值为0。更新过了,就让返回值为ans;
}
};
【滑动窗口求解】本质上也可理解为双指针,滑动窗口是一种形象化的说法,我们本质上是定义了两个指针start 和end,通过移动两个指针来改变“窗口”(数组)的大小和位置。每次滑动这个窗口就进行一次求和,与前一次的和进行比较,如果比较小就更新,比较大就进入下一轮的求和计算,这里和暴力求解思路有点类似,不同的地方在于我们借助指针start的移动,避免了部分重复,减少了运算的数据规模。(每更新一次和,就将这个数组的start往前移动一位,start++,去掉第一个数组元素)。返回时再进行一次判断,看有没有真的实现更新,这个和暴力求解时说的一样。
完整求解代码如下:
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int n=nums.size();
int ans=INT_MAX;
int start=0,end=0;
int sum=0;
while(end= target)
{
ans=min(ans,end-start+1);
sum -= nums[start];
start++;
}
end++;
}
return ans==INT_MAX? 0 : ans;
}
};
3.原题链接:leetcode59螺旋矩阵
【收获4】区间的定义和使用原则要统一;比如都是用左闭右开。
【题解思路】
先定义每个循环圈的起始位置(startx,starty),要考虑到行列数是奇数还是偶数,这决定了有几个圈,如果是奇数,最后一个圈实际上就是一个元素,可以不参与循环单独处理,如果是偶数就不存在这最后一个元素,可以全部用循环来计算和赋值。
int loop = n / 2 ;//loop,每个圈循环几次,比如n=3,那么loop=1只是循环一圈,最中间的元素单独处理
以第一圈为例,我们先填充top第一行,填充范围是(0,n-1),此时变的是列标 j 的值;
for(j = starty; j< n - offset; j++)//这里用offset不直接用1是因为进入下一层循环时,被赋值的数组元素个
//数会减少一个。每完成一次循环就需要减1;
{
res[i][starty]=count++;//这里的count初始值为1,每次+1,用来给数组中每一个元素赋值
}
然后填充右侧第一列,填充范围是(0,n-1),此时变的是行标 i 的值。
for(i = startx;i < n - offset; i++)
{
res[startx][j]=count++; //这里之所以再另外设置一个startx,一个starty,是因为每进行完一圈
// 的赋值,就需要缩小这个数组行列的边界一次.
}
再填充底部最后一行,从右往左,填充范围是(0,n-1),此时变的是列标 j 的值。
for(; j>0;j--)
{
res[i][j]=count++;
}
第一圈的最后给左侧第一列从下往上赋值,填充范围是(0,n-1),此时变的是行标 i 的值
for(; i>0; i--)
{
res[i][j]=count++;
}
每次结束一圈,就进行一次边界缩小
startx++;
starty++;
offset +=1;//每次需要被n减去的值要增加一个
另外要在循环结束后记得判断一下是不是奇数行列,如果是奇数,会留下一个最中间的位置等待赋值。
if(n%2!=0)
{
res[mid][mid]=count;//这里不是count++;count++的意思是先给count位置处赋值,然后让count++,前面
//的循环已经让它+1了。
}
完整求解代码如下:
class Solution {
public:
vector> generateMatrix(int n) {
vector>res(n,vector(n,0));
int startx=0,starty=0;
int loop=n/2;
int mid = n / 2;
int count = 1;
int offset = 1;
int i,j;
while (loop --){
i = startx;
j = starty;
for(j = starty;jstarty;j--){
res[i][j]=count++;
}
for(;i>startx;i--)
{
res[i][j]=count++;
}
startx++;
starty++;
offset += 1;
}
if(n%2!=0)
{
res[mid][mid]=count;
}
return res;
}
};
【收获5】用vector定义二维数组,同时使用已有的一维数组范围。
vector>res(n,vector(n,0));