代码随想录算法学习心得2 |977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵...

目录

一、有序数组的平方

思路:

注意事项:

代码如下:

结果如下:

 二、长度最小的子数组

思路:

1.暴力求解代码如下:

2.动态窗口法代码如下:

运行结果如下:

 三、螺旋矩阵

思路:

 注意

代码如下:

运行结果:


一、有序数组的平方

链接:力扣1

描述:给你一个按非递减顺序 排序的整数数组 nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。


思路:

1.可以先对原数组遍历数据,再求平方,再进行排序。

2.利用双指针法。数组里可能包含有负数,由于nums数组是非递减顺序的,平方后的最大值只可能出现在两端,可考虑两个指针由两端向内部遍历,注意,本题是按非递减顺序来输出,所以新数组的下标要从大到小。


注意事项:

1.while循环里left=right也可以。

2.vector容器需要设定容器大小。

3.若存在right和left指向的值相等,取其中任意一个都行,另一个在下一次循环中会作为较大值被添加到新数组中。

4.本题使用了for_each遍历容器,需要加头文件<algorithm>


代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution
{
public:
	vector<int> sortedSquares(vector<int>& nums)
	{
		vector<int>result;
		result.resize(nums.size());
		int n = result.size()-1;
		int left = 0;
		int right = nums.size() - 1;
		while (left <= right)
		{
			if (pow(nums[right], 2) > pow(nums[left], 2))
			{
				result[n--] = pow(nums[right], 2);
				right--;
			}
			else
			{
				result[n--] = pow(nums[left++], 2);
			}
		}
		return result;
	}
};
void printvector(int elem)
{
	//打印容器里的元素
	cout << elem << " ";
}
int main()
{
	vector<int>v = { -7,-3,2,3,11 };
	Solution s;
	vector<int>result = s.sortedSquares(v);
	for_each(result.begin(), result.end(), printvector);
	return 0;
}

结果如下:

 二、长度最小的子数组

链接:力扣2

描述:给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。


思路:

1、使用暴力求解,用两个for循环得到所有的数组的子数组,并求和来判断是否大于或等于target,满足条件则求出子数组的长度。

2、动态窗口。只用一个for循环,不断调节子数组的起始位置和终止位置。那么问题在于确定以下三方面:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口内是满足和大于等于target的元素。

如果当前的窗口内的元素满足要求了,则缩小窗口,即需要不断减少元素,从而窗口内的元素和不断减小,对应于一个while循环,里边起始位置i增大。当循环终止时,得到最小的子数组长度。


1.暴力求解代码如下:

时间复杂度为o(n^{2}),在LeetCode里ac不了,提示超时。

#include <iostream>
#include <vector>
using namespace std;
class Solution
{
public:
    int minSubArrayLen(int target, vector<int>& nums)
    {
        //暴力求解
        int sublength = 0;//子数组的长度
        int result = INT32_MAX;//最后的结果
        int sum = 0;
        for (int i = 0; i < nums.size(); i++)
        {
            sum = 0;
            //i是起始,j是终止
            for (int j = i; j < nums.size(); j++)
            {
                sum += nums[j];
                if (sum >= target)
                {
                    sublength = j - i + 1;
                    result = result < sublength ? result : sublength;
                    break;//退出该内层循环,因为多加没有意义了
                }
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

int main()
{
    vector<int>v{ 1,1,1,1,5,8,9 };
    Solution s;
    int ret=s.minSubArrayLen(10, v);
    return 0;
}

 

2.动态窗口法代码如下:

注意:

 while (sum >= target)中不能使用if判断,因为需要不断去更新i的位置,如果改了的话,会导致得到的子数组长度不是最小。

#include <iostream>
#include <vector>
using namespace std;
class Solution
{
    public:
        int minSubArrayLen(int target, vector<int>& nums) 
        {
            int i = 0;//窗口的起始位置
            int sublength = 0;//子数组的长度
            int sum = 0;
            int result = INT32_MAX;//最终的子数组长度
            for (int j = 0; j < nums.size(); j++)
            {
                //j是窗口终点位置
                sum += nums[j];
                while (sum >= target)
                {
                    sublength = j - i + 1;
                    result = result < sublength ? result : sublength;
                    sum -= nums[i++];
                }
            }
            return result == INT32_MAX ? 0 : result;
        }
};
int main()
{
    Solution s;
    vector<int>v = { 1,2,3 };
    int ret=s.minSubArrayLen(5,v);
	return 0;
}

 

运行结果如下:


 三、螺旋矩阵

链接:力扣3

描述:给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。


思路:

把握循环不变量原则:对于矩阵每一条边的处理要一致,左闭右开或者左闭右闭。

用二维容器来接收。矩阵的产生过程如下:

当n为奇数时,需要对于中间元素单独处理。

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

 

注意

1.需要设置一个偏移量,每次循环后需要加1,开始的x和y下标也要随着更新。

2.循环次数为n/2。


代码如下:

#include <iostream>
#include <vector>
using namespace std;
class Solution
{
public:
	vector<vector<int>> generateMatrix(int n)
	{
		//二维容器,初始化为n个一维容器,且初值为0
		vector<vector<int>>res(n, vector<int>(n, 0));
		int startx = 0;//开始的x下标
		int starty = 0;//开始的y下标
		int mid = n / 2;//用于n为奇数的情况
		int i, j=0;
		int count = 1;
		int offset = 1;//偏移量
		int loop = n / 2;//转圈次数
		while (loop)
		{
			i = startx;
			j = starty;
			for (j = starty; j < n - offset; j++)
			{
				//不包含每一条边界的最后一个元素
				res[i][j] = count++;
			}
			for (i = startx; 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 += 1;
			loop--;
		}
		if (n % 2 == 1)
			//奇数的情况需要单独讨论
			res[mid][mid] = count;
		return res;
	}
};
int main()
{
	vector<vector<int>>v;
	Solution s;
	v = s.generateMatrix(1);
	return 0;
}

运行结果:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值