从0开始学算法1:一套图 搞懂“时间复杂度”

9 篇文章 0 订阅 ¥49.90 ¥99.00

写在前面:
这篇文章是在公众号: 趣谈编程 中发布的,作者是涛声依旧。是我到目前为止所看到的关于时间复杂度介绍的最好的文章,简介 清晰 明了。

所以拿来po出来 仅供学习交流,如侵则删。

正文:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

另外,我这里有个问题,现在计算机硬件越来越强大了,为什么还这么重视时间复杂度呢?

我们来举过一个栗子:

算法A的相对时间规模是T(n)= 100n,时间复杂度是O(n)

算法B的相对时间规模是T(n)= 5n2,时间复杂度是O(n2)

算法A运行在小邦家里的老旧电脑上,算法B运行在某台超级计算机上,运行速度是老旧电脑的100倍。

那么,随着输入规模 n 的增长,两种算法谁运行更快呢?

在这里插入图片描述
从表格中可以看出,当n的值很小的时候,算法A的运行用时要远大于算法B;当n的值达到1000左右,算法A和算法B的运行时间已经接近;当n的值越来越大,达到十万、百万时,算法A的优势开始显现,算法B则越来越慢,差距越来越明显。

这就是不同时间复杂度带来的差距。

要想学好算法,就必须理解好时间复杂度这个重要的基石。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一套完整的大一数据结构C语言版期末算法大题及答案: 1. 有一个长度为 n 的整数数组 nums,其中有一个重复出现了两次,另外 n-2 个数字各不相同。请找出这个重复的数字。要求时间复杂度为 O(n),空间复杂度为 O(1)。请编写程序实现算法。 2. 给定一个长度为 n 的整数数组 nums,其中每个元素都是 1 到 n 之间的整数,但是有一个元素重复了两次,另外一个元素缺失了。请找出这两个元素,并返回它们。要求时间复杂度为 O(n),空间复杂度为 O(1)。请编写程序实现算法。 3. 给定一个无序整数数组 nums,要求对该数组进行快速排序,并输出排序后的结果。要求时间复杂度为 O(n log n),空间复杂度为 O(log n)。请编写程序实现算法。 4. 给定一个 G,其中每个顶点的度数均为偶数。请找出 G 的欧拉回路,并输出该回路的路径。要求时间复杂度为 O(V+E),空间复杂度为 O(E)。请编写程序实现算法。 5. 给定一个长度为 n 的字符串 s,要求对该字符串进行 Huffman 编码,并输出编码后的结果。要求时间复杂度为 O(n log n),空间复杂度为 O(n)。请编写程序实现算法。 答案: 1. 可以使用异或运算来解决这个问题,因为异或运算满足以下性质:a^b^b=a,a^b^a=b。因此,我们可以遍历整个数组,对每个数字进行异或运算,如果出现了重复的数字,那么最终的异或结果就是这个数字。具体实现如下: ```c int findDuplicate(int* nums, int numsSize){ int res = 0; for (int i = 0; i < numsSize; i++) { res ^= nums[i]; res ^= i; } return res; } ``` 2. 这个问题可以转化为求解以下两个方程组: x + y = sum - n(n+1)/2 x^2 + y^2 = sumOfSquares - n(n+1)(2n+1)/6 其中,sum 表示数组中所有元素之和,sumOfSquares 表示数组中所有元素的平方之和。根据这两个方程组,我们可以求出 x 和 y 的值,进而得到重复的元素和缺失的元素。具体实现如下: ```c int* findErrorNums(int* nums, int numsSize, int* returnSize){ int* res = (int*)malloc(sizeof(int) * 2); int sum = 0, sumOfSquares = 0; for (int i = 0; i < numsSize; i++) { sum += nums[i]; sumOfSquares += nums[i] * nums[i]; } int diff = sum - numsSize * (numsSize + 1) / 2; int diffSquare = sumOfSquares - numsSize * (numsSize + 1) * (2 * numsSize + 1) / 6; int xPlusY = diff; int xMinusY = sqrt((long long)diff * diff - 4 * diffSquare); int x = (xPlusY + xMinusY) / 2; int y = (xPlusY - xMinusY) / 2; res[0] = y; res[1] = x; *returnSize = 2; return res; } ``` 3. 快速排序算法的核心思想是分治法。具体实现如下: ```c void quickSort(int* nums, int left, int right){ if (left >= right) { return; } int i = left, j = right; int pivot = nums[left]; while (i < j) { while (i < j && nums[j] >= pivot) { j--; } nums[i] = nums[j]; while (i < j && nums[i] <= pivot) { i++; } nums[j] = nums[i]; } nums[i] = pivot; quickSort(nums, left, i - 1); quickSort(nums, i + 1, right); } ``` 4. 欧拉回路的存在条件是: G 是连通的,并且 G 中每个顶点的度数均为偶数。欧拉回路的求解方法是 Fleury 算法。具体实现如下: ```c void euler(int u){ for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (!vis[u][v]) { vis[u][v] = vis[v][u] = true; euler(v); ans.push_back(u); } } } ``` 5. Huffman 编码的核心思想是贪心算法。具体实现如下: ```c typedef struct TreeNode{ int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; TreeNode* createNode(int val){ TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->val = val; node->left = NULL; node->right = NULL; return node; } TreeNode* buildHuffmanTree(int* freq, int n){ PriorityQueue* pq = createPriorityQueue(n); for (int i = 0; i < n; i++) { enqueue(pq, createNode(freq[i])); } while (size(pq) > 1) { TreeNode* left = dequeue(pq); TreeNode* right = dequeue(pq); TreeNode* parent = createNode(left->val + right->val); parent->left = left; parent->right = right; enqueue(pq, parent); } TreeNode* root = dequeue(pq); destroyPriorityQueue(pq); return root; } void dfs(TreeNode* node, char* path, int depth, char** res, int* returnSize){ if (!node->left && !node->right) { path[depth] = '\0'; res[*returnSize] = (char*)malloc(sizeof(char) * (depth + 1)); strcpy(res[*returnSize], path); (*returnSize)++; return; } if (node->left) { path[depth] = '0'; dfs(node->left, path, depth + 1, res, returnSize); } if (node->right) { path[depth] = '1'; dfs(node->right, path, depth + 1, res, returnSize); } } char** huffman(int* freq, int n, int* returnSize){ TreeNode* root = buildHuffmanTree(freq, n); char* path = (char*)malloc(sizeof(char) * (n + 1)); char** res = (char**)malloc(sizeof(char*) * n); *returnSize = 0; dfs(root, path, 0, res, returnSize); return res; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值