Topic 01 recap
1.1
PrintN 打印N:
void printN(int n) {
for (int i = 1; i <= n; i ++) {
printf("%d\n", i);
}
}
void printN1(int n) {
if (n) {
printN1(n - 1);
printf("%d\n", n);
}
}
PrintN与PrintN1打印数字一个采用循环打印,一个采用递归打印,当n的值过大时,则第二个打印会直接失败,因为递归所占用的内存超出限制
计算一元二次函数
double f1(int n, double x) {
double res = 1;
for (int i = 1; i <= n ; ++i) {
res += pow(x, i) / i;
}
return res;
}
double f2(int n, double x) {
double res = 0;
for (int i = n; i > 0; --i) {
res = res * x + 1.0 / i;
}
res += 1;
return res;
}
-
对于时间的计算,由于程序过快,故采用运行
1e7次的时间(由于单次运行时间非常短,可能无法精确测量,因此通过重复运行多次来累积时间,然后除以运行次数来得到平均单次运行时间。这种方法可以提高测量精度),然后除1e7得到平均一次运行的时间 -
对于 f1 采用一般的方法进行计算,对于 f2 采用秦九韶方法进行计算,得出的时间前者比后者多一个数量级别
关于抽象
-
抽象只关注问题的解决思路;
-
不关注处理的对象,进行操作的具体细节,便于设计 广泛的解决方法 处理同样原理的问题;
-
提高 一种思路 的 普遍适用性。
1.2
算法定义
- 一个有限指令集
- 接受一些输入
- 产生输出
- 一定在有限步骤后终止
- 每一条指令必须
- 有充分的目标,不可以有歧义
- 计算机能处理的范围之内
- 描述应不依赖于任何一种计算机语言及具体实现手段
时间与空间复杂度
O(n)来评判,一般通过最坏的情况来判断一个程序的时间复杂度
空间复杂度类似
简单二分查找的时间复杂度计算
第一次比较后范围数:n / 2
第二次比较后:n / 4
第三次比较后:n / 8
...
假设第k次的范围数为1,也就是最坏的情况下,找到了数或没找到数(在比较时间复杂度是时候并不关心底数2还是10)
程序如下:
#include <stdio.h> int binary_search(const int x, const int arr[], const int n) { int l = 0, r = n - 1; while(l <= r) { int m = l + r >> 1; if(arr[m] == x) return m; if(arr[m] < x) l = m + 1; else r = m - 1; } return -1; } int main() { int arr[] = {1, 3, 4, 8, 54, 60, 100, 211}; int x = 54; int n = sizeof(arr) / sizeof(arr[0]); int index = binary_search(x, arr, n); printf("Index of %d is %d\n", x, index); return 0; } // 1. 二分查找的前提是数组有序 // 2. 二分查找的时间复杂度是O(logn) // 3. 二分查找的空间复杂度是O(1) // 4. 二分查找的缺点是数组必须是有序的,如果数组是无序的,需要先排序 // 5. 二分查找的优点是速度快,时间复杂度低 // 6. 二分查找的应用场景是在有序数组中查找某个元素的位置
关于PTA作业:PTA Link
Position BinarySearch( List L, ElementType X ) {
Position l = 0, r = L->Last;
while(l <= r) {
Position mid = l + r >> 1;
if (X == L->Data[mid]) return mid;
if (X < L->Data[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return NotFound;
}
1.3
当我们有一个程序是O(n^2),我们要试想下能不能简化成O(nlog(n))
最大子序列和问题
[!note]
- O(n^3)
- O(n^2)
- O(nlog(n)) 分治法
- O(n)
// O(n)
#include <iostream>
#include <vector>
int main() {
int n; std::cin >> n;
std::vector<int>arr(n);
for (int& elem : arr) std::cin >> elem;
int res = 0, temp = 0;
for (const int& elem : arr) {
temp += elem;
if (temp > res) {
res = temp;
} else if (temp < 0) {
temp = 0;
}
}
std::cout << res;
return 0;
}
返回前后数版本:PTA Link
#include <iostream>
#include <vector>
int main() {
int n; std::cin >> n;
std::vector<int>arr(n);
for (int& a : arr) std::cin >> a;
int maxRes, temp, beg, end, last;
maxRes = - 1;
temp = beg = last = end = 0;
for (int i = 0; i < n; i++) {
temp += arr[i];
if (temp > maxRes) {
maxRes = temp;
beg = last;
end = i;
} else if (temp < 0) {
temp = 0;
last = i + 1;
}
}
if (maxRes < 0) std::cout << 0 << " " << arr[0] << " " << arr[n - 1];
else std::cout << maxRes << " " << arr[beg] << " "<< arr[end];
return 0;
}
End...