编程作业(1)

因为作业代码涉及隐私,所以文章只提供解题思路和有关拓展,若实在需要源码可以私信

作业:

习题课作业:
	用更快更好的算法算上课第一个演示程序(找前个数位之和等于后几个数位之和的数的个数。如abcdef,	
	需a+b+c=d+e+f)。并且能够在程序中比较方法之间的优劣:内存占用,运行时间等参数。

全部跳过直接看解题算法点这里:↓↓↓↓↓↓


写在前面

1, 如何在递归中使用指针来表示数组结尾(传入一个一直指向指针头部的参数, 并利用它表示出数组的范围)
2,指针参数的自增需要注意是先增还是后增,尾递归add(arr++, p)和add(++arr, p)是不同的结果
3,多维数组的声明需要将双箭头用空格隔开 std::vector<std::vector<float> > //right!
4,for循环的终止条件和变化方式是不一定必须写在开头括号里的,也可以写在循环体内部以便灵活使用
5,vector的push_back,只可以push进其“规定类型”的“一个”元素。
    eg:三维数组可push进一个二维数组,一维int数组push进入一个int
6,在多层循环中可以将一些语句尽量放在外层循环中,时间复杂度不变,但是可以减少运算量
7,通过更缜密的数学推理,可以获得更优美的代码

有关拓展

|| 为了求数组中每一个数的平方和,写了个使用指针的递归函数 稍微复习

//明确函数功能:求出放入的数组的平方
//定好尾头:尾:数组中无值  头:第一个数求好平方后加第二个数的平方 
int add(int* arr, int *p) {
	if(arr > p+(sizeof(p)/sizeof(*p))  )
		return 0;
	return *arr * (*arr) + add(++arr,p);
}

|| 可以用c++自制一个python中的map高级函数,用于返回数组的个元素平方和

////////////////////////
后续补充
////////////////////////

|| 回忆类似写法的leetcode题,使用双指针使得数组返回三数之和的

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。 
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],	
满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

解题思路:最重要的是去重操作(即跳步操作)
#include<iostream>
using namespace std;
#include <vector>
#include <algorithm>

class Solution {
public:
	vector<vector<int>> threeSum(vector<int>& nums) {
		vector<vector<int>> res;
		if (nums.size() < 3) return res;
		sort(nums.begin(), nums.end());
		for (vector<int>::iterator it = nums.begin(); it != nums.end() - 2;) {
			int tmp = *it;
			if (tmp > 0) break;
			int target = 0 - tmp;
			vector<int>::iterator left = it + 1;
			vector<int>::iterator right = nums.end() - 1;
			while (left < right) {
				if (*right < 0) break;
				if (*left + *right < target) {
					int v = *left;
					while (left != right && *left == v) left++; //跳过相等的元素
				}
				else if (*left + *right > target) {
					int v = *right;
					while (left != right && *right == v) right--;//跳过相等的元素
				}
				else {
					vector<int> tmp_res{ tmp,*left,*right };
					res.push_back(tmp_res);
					int v = *left;
					while (left != right && *left == v) left++;//跳过相等的元素
					v = *right;
					while (left != right && *right == v) right--;//跳过相等的元素
				}
			}
			while (it != nums.end() - 2 && *it == tmp) it++;//跳过相等的元素
		}
	}
};

解题思路:
解优化题:正常的思路

正常的思路是使用多层循环,在多层循环中可以将一些语句尽量放在外层循环中,时间复杂度不变,
但是可以减少运算量 eg: 将a+b在外层提前运算后,再将其和放进内层中运算
#include<iostream>
using namespace std;
#include <time.h>

int main(int argc, char** argv) {
	int num = 0;
	int res = 0;
	int ab, abc, de;
	for (int a = 0; a < 6; a++)
		for (int b = 0; b < 6; b++) {
			ab = a + b;
			for (int c = 0; c < 6; c++)
			{ 
				abc = ab + c;
				for (int d = 0; d < 6; d++)
					for (int e = 0; e < 6; e++){
						de = d + e;
						for (int f = 0; f < 6; f++) {
							if (abc == de + f)
								res++;
						}
					}
			}
		}
		
	cout<< "////////////" << endl;
	cout << "result:\t " << res << endl;
	cout << "///////////" << endl;
	return 0;
}

更高效的算法

通过位数最高值为 0~6 的 6位数 寻找规律,可以获得下图规律

6位数 需要 分成两个3位数,若该6位数满足条件则其两个3位数之和相等,求出三位数每种和可能出
现的种类,其该和的三位数种类^2 (排列组合) 即成功搭配出所有满足条件的6位数。
eg: 和为2的三位数 110 /101/011 /020/200/002 它们进行搭配可得出满足条件的6位数

因此我们将目光放在3位数上

1,先获得三位数为 00n ,0nn,和nnn的情况,即三位数的位数之和为1-18的所有情况,我们使用矩阵
注意:(x,y)中,x是可能的位数和,通过y可以将每个x值对应的y值求和得到∑y,
2,如图:黄色部分每个位上可能出现的数字,黄色部分下方/右方的数字是其对应黄色数字已有的搭配
图一表示两位数与两位数,其每个和(即x)的搭配结果(即∑y)称为图二对应的左列!
注意:两位数之间的搭配结果刚好是个d=1递增的数列 【1,2,3,4,5,6,5,4,3,2,1】
重复以上步骤,可求出结果,修改相关数据可求出0~x 任意位数的符合条件解

在这里插入图片描述
在这里插入图片描述


以下 关于0~6 的 6位数 的运算代码,根据规律改动相关数据即可称为 0~x 任意位数 的代码

#include<iostream>
using namespace std;
#include<vector>


int*** spisok() {

	int*** arr_np3D = arr_np3D = (int***)new int** [11];


	for (int x = 0; x < 11; x++)
	{
		arr_np3D[x] = (int**)new int* [6];

	}

	for (int x = 0; x < 11; x++)
	{
		int arr[] = { 1,2,3,4,5,6,5,4,3,2,1 };
		for (int y = 0; y < 6; y++)
		{
			arr_np3D[x][y] = new int[2];
			arr_np3D[x][y][0] = x + y + 3;
			arr_np3D[x][y][1] = arr[x];
		}

	}

	return arr_np3D;

}

int getRes(){
	int*** arr_np3D = spisok();
	int arr[16] = {0};
	int res = 0;
	
	for (int x = 0; x < 11; x++)
	{
		for (int y = 0; y < 6; y++)
		{
			
				arr[arr_np3D[x][y][0] - 3] += arr_np3D[x][y][1];
		}

	}
	

	for (int i = 0; i < 16; i++)
	{
		res += arr[i]*arr[i];
	}
	
	return res;
	
}
发布了50 篇原创文章 · 获赞 73 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/a13352912632/article/details/104644318
今日推荐