Day2 有序数组的平方,长度最小的子数组,螺旋矩阵

 有序数组的平方

题目是一个非递减的数组让我们来写他得每一个元素平方后,输出另一个新的非递减的数组。关于这个道题第一想法就是如果我能在还没有平方之前就按照从小到大的顺序那么不就是直接满足这个题的条件

#include<iostream>
#include<algorithm>
using namespace std;
void shuchu(int arr[])
{
	sort(arr, arr+5);
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] * arr[i] << " ";
	}
}
int main()
{
	int arr[5];
	for (int i = 0; i < 5; i++)
	{
		int num;
		cin >> num;
		arr[i] = num;

	}
	shuchu(arr);
}

        对于下面这个代码,真是漏洞百出,刚开始我认为如果把数大的放在后面那么不就满足题意了么?

       但是当我开始运行的时候我发现这个result这个数组后面正常但是前面却开始乱码,于是思考之路开始了,原来我就是只考虑了这个数组的后面没有考虑前面,那当我运行的时候就会产生乱码的现象。

        看看我写的这个代码,这个只有i last所以无法保证 就算没有乱码这么写也是不对的

#include<iostream>
using namespace std;
int main()
{
	int arr[5];
	int result[5];
	for (int i = 0; i < 5; i++)
	{
		int num;
		cin >> num;
		arr[i] = num;
	}
	//int begin = 0;
	int last = 4;
	for (int i = 0; i <= last; )
	{
		if (arr[i] * arr[i] > arr[last] * arr[last])
		{
			result[last--] = arr[i] * arr[i];
			i++;
			cout << "";
		}
		else
		{
			result[last--] = arr[last] * arr[last];
		}
	}
	for (int i = 0; i < 5; i++)
	{
		cout << result[i] << " ";
	}
}

在我不停的纠错过程中,我看到了自己的错误,这里补充一句,有错误不可怕,可怕的是错误永远不改正。

在这个新写的代码中我利用了i j k通过这三个变量,促使我的代码开始走向正确之路! 

#include<iostream>
using namespace std;
int main()
{
	int arr[5];
	for (int i = 0; i < 5; i++)
	{
		int num;
		cin >> num;
		arr[i] = num;

	}
	int result[5];
	int k = 4;
	for (int i = 0, j = 4; i <= j;)
	{
		if (arr[i] * arr[i] > arr[j] * arr[j])
		{
			result[k--] = arr[i] * arr[i];
			i++;
		
		}
		else
		{
			result[k--] = arr[j] * arr[j];
			j--;
		}
	}
	for (int i = 0; i < 5; i++)
	{
		cout << result[i] << " ";
	}

}

最后总结一下所有优化过的代码都是在原本暴力的算法上进行改良。

长度最小的子数组

这题意是给定一个数找到连续相加和符合这个目标的最小子数组

暴力算法求解:利用两个双循环,对于每个数都向后不停的累加 发现不成功就换一个数

#include<iostream>
using namespace std;
//#include <cstdint> // for INT32_MAX
//#include <climits> // for INT_MAX
int main()
{
	int arr[5];
	
	for (int i = 0; i < 5; i++)
	{
		int num;
		cin >> num;
		arr[i] = num;
	}
	int target;
	int result = INT32_MAX;
	cin >> target;
	for (int i = 0; i < 5; i++)
	{
		int sum = 0;
		for (int j = i; j < 5; j++)
		{
			sum += arr[j];
			if (sum == target)
			{
				result = (j - i + 1) < result ? (j - i + 1) : result;
			}
		}
	}
	if (result == INT32_MAX)
	{
		cout << "no";
	}
	else
	{
		cout << result;
	}
}

 以下这个代码运用了滑动窗口,所谓滑动窗口就是利用两个指针i和j其中j这个指针向后移动来进行累加,如果发现现在累加求和的这个值如果比目标值小,就利用j向后进行加加,如果发现累加的这个和比目标值大,就将这个和减去i,使得j向后移动是为了加,i向后移动是为了减,但是这样做就相当于是不用像暴力算法一样,让指针多次从头开始,但是我们需要注意的地方在于这个j-i不用再+1了

#include<iostream>
using namespace std;
int main()
{
	int result = INT32_MAX;
	int arr[5];
	
	for (int i = 0; i < 5; i++)
	{
		int num;
		cin >> num;
		arr[i] = num;
	}
	int target;
	cin >> target;
	int sum = 0;
	for (int i = 0,j=0; i < 5; )
	{
		
		
		if (sum < target)
		{
			sum += arr[j];
			j++;
		}
		if (sum == target)
		{
			result = (j - i) < result ? (j - i ) : result;//这个地方不用+1  因为上面j++
			//sum = 0;//这个地方不是置0
			sum -= arr[i];
			i++;
		}
		if (sum > target)
		{
			sum -= arr[i];
			i++;
		}
	}
	if (result == INT32_MAX)
	{
		cout << "no";
	}
	else
	{
		cout << result;
	}
}

对于下面这个代码相当于是将我们上面那个代码中的三个if进行压缩使用一个while循环 

#include<iostream>
using namespace std;
int main()
{
	int result = INT32_MAX;
	int arr[5];
	
	for (int i = 0; i < 5; i++)
	{
		int num;
		cin >> num;
		arr[i] = num;
	}
	int target;
	cin >> target;
	int sum = 0;
	for (int i = 0,j=0; i < 5; )
	{
		
		
		if (sum < target)
		{
			sum += arr[j];
			j++;
		}
		//if (sum == target)
		//{
		//	result = (j - i) < result ? (j - i ) : result;//这个地方不用+1  因为上面j++
		//	//sum = 0;//这个地方不是置0
		//	sum -= arr[i];
		//	i++;
		//}
		//if (sum > target)
		//{
		//	sum -= arr[i];
		//	i++;
		//}
	while (sum >=target)
		{
		if(sum==target)
			result = (j - i) < result ? (j - i) : result;
		
			sum -= arr[i];
			i++;
		}
	
	}
	if (result == INT32_MAX)
	{
		cout << "no";
	}
	else
	{
		cout << result;
	}
}

螺旋矩阵

这道题的题意是请输出一个顺时针的螺旋矩阵,对于这道题我们要坚持一个循环不变量。

 首先我们需要知道这个螺旋矩阵在我们进行循环的时候需要有几行循环,其次我们要精准的记住这个不变量的原则就是坚持左闭右开的原则,这个跟我们再写二分的时候很像(如果想了解去看看我的另一个笔记吧!)面对这道题刚开始我的错误就在于是下行和左列,因为我没有很好的来规划i和j的范围,以及我们在这个startx和starty我们应该正确的开始!

另一个很重要的点在于这个n是否是奇数!!!

另一个很重要的点在于我们要记住包括左面,不包括右面!!!

有一个点在于是几圈

#include<iostream>
using namespace std;
int main()
{
	int arr[10][10];
	int n;
	cin >> n;
	int circle = n / 2;
	int back = 1;
	
	int startx = 0,starty=0,start=1;

	while (circle--)
	{
		int i = startx;
		int j = starty;
		
		for (j; j< n - back; j++)
		{
			arr[i][j] = start++;

		}
		for (i; i < n - back; i++)
		{
			arr[i][j] = start++;
		}
		for (j; j > starty; j--)
		{
			arr[i][j] = start++;
		}
		for (i; i >startx; i--)
		{
			arr[i][j] = start++;
		}
		if (n % 2 != 0)
		{
			arr[n/2][n/2] = start;
		}
		back++;
		startx++;
		starty++;
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}
}

 

以上是一个n=4的图  我们要坚持左闭右开 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值