包括但不限于以下内容:
- Basic Data Structure and Algorithms
- Design techniques of Algorithms
- Databases
- Concurrency Algoritms
- Shell Programming
- Analisys of time and space complexity
- LeetCode2.cpp Add Two Numbers AC
- LeetCode6.cpp ZigZag Conversion AC 等差数列题目
- LeetCode12.cpp Integer to Roman AC
- LeetCode14.cpp Longest Common Prefix AC
- LeetCode7.cpp reverse AC
- LeetCode9.cpp isPalindrome AC
- LeetCode29.cpp Divide Two Integers AC
- LeetCode13.cpp romanToInt AC
- LeetCode1351.cpp Count Negative Numbers in a Sorted Matrix AC
- LeetCode8.cpp String to Integer (atoi) AC
- LeetCode240.cpp Search a 2D Matrix II 采用二分检索存在TLE,存在一个O(r+c)的线性时间算法
- LeetCode54.cpp AC 矩阵搜索,n皇后问题也用到了类似的技巧
- LeetCode80.cpp Remove Duplicates from Sorted Array II AC LeetCode26 follow-up
- LeetCode415.cpp Add to Array-Form of Integer AC
- LeetCode989.cpp Add to Array-Form of Integer AC
- LeetCode67.cpp Add Binary AC
- LeetCode43.cpp Multiply Strings AC
- Cycle Detection Algorithms 本题考查环检测算法,具体见链接 https://en.wikipedia.org/wiki/Cycle_detection
- KMP
- Manacher
- 双指针问题包括(前向型指针(滑动窗口(将O(n^2)算法做成O(n)的算法)和快慢指针两类)、相向型指针(O(n))、两个数组(典型题目为mergesort中的merge过程)三种大类)
- LeetCode167.cpp Two Sum II - Input array is sorted 相向型指针 AC
- LeetCode88.cpp Merge Sorted Array AC
- LeetCode1.cpp Two Sum AC
- LeetCode15.cpp 3Sum two pointer AC
- LeetCode16.cpp 3Sum Closest AC
- LeetCode18.cpp 4Sum two pointer AC 相向型指针
- LeetCode713.cpp Subarray Product Less Than K AC
- LeetCode3.cpp Longest Substring Without Repeating Characters AC
- Leetcode209.cpp Minimum Size Subarray Sum AC
- LeetCode76.cpp Minimum Window Substring O(256n) AC
- LeetCode628.cpp Maximum Product of Three Numbers AC
- LeetCode21.cpp merge Two Lists AC
- LeetCode4.cpp find Median Sorted Arrays AC
- LeetCode493.cpp Reverse Pairs AC 相向型指针
- LeetCode11.cpp Container With Most Water AC 相向型指针
- LeetCode26.cpp Remove Duplicates from Sorted Array AC 前向型指针
- LeetCode27.cpp Remove Element AC 前向型指针
- LeetCode392.cpp Is Subsequence AC 两个指针
- one dimemsion prefix sum
- two dimension prefix sum
- LeetCode912.cpp Sort an Array AC
- implement quicksort (最快,最省空间)
- implement merge sort
- implement heap sort
- Cyclic Sort
- Counting Sort & Radix Sort
- LeetCode56.cpp Merge Intervals AC sort+greedy
- LeetCode57.cpp Insert Interval AC sort+greedy给出了两种方法,都能AC
- LeetCode986.cpp Interval List Intersections AC merge的部分实际上和mergesort中的merge有异曲同工之处
- LeetCode435.cpp Non-overlapping Intervals AC sort+greedy method
- LeetCode452.cpp Minimum Number of Arrows to Burst Balloons AC sort+greedy求相邻区间的交集
- LeetCode1288.cpp Remove Covered Intervals AC sort+greedy
- LeetCode218.cpp The Skyline Problem
- LeetCode436.cpp Find Right Interval AC 解法是利用map,line sweep重点步骤是按照key排序,这里使用map本身的排序特性代替
- LeetCode324.cpp Wiggle Sort II AC O(nlogn)
- map and set
- LeetCode981.cpp Time Based Key-Value Store unordered_multimap is time limited, but map is accepted
- LeetCode287.cpp Find the Duplicate Number AC
- LeetCode414.cpp Third Maximum Number unordered_map + priority_queue O(n) AC
- LeetCode1089.cpp Duplicate Zeros AC
- LeetCode239.cpp Sliding Window Maximum AC multiset
- LeetCode480.cpp Sliding Window Median AC multiset
- LeetCode540.cpp Single Element in a Sorted Array AC
- LeetCode350.cpp Intersection of Two Arrays II Hashtable O(n) AC
- LeetCode217.cpp Contains Duplicate AC hash table 去重
- SimulateHashTable.cpp 拉链法解决冲突
- SimulateHashTable.cpp 开放寻址法解决冲突
- priority_queue and map/set can exchange at the solving min/max problem.
- Trie
- priority_queue
- LeetCode658.cpp Find K Closest Elements AC
- LeetCode703.cpp Kth Largest Element in a Stream AC
- LeetCode973.cpp K Closest Points to Origin AC
- LeetCode692.cpp Top K Frequent Words AC
- LeetCode347.cpp Top K Frequent Elements AC
- LeetCode451.cpp Sort Characters By Frequency AC
- LeetCode215.cpp Kth Largest Element in an Array O(n+k*logn) AC
- LeetCode414.cpp Third Maximum Number unordered_map + priority_queue O(n) AC
- LeetCode378.cpp Kth Smallest Element in a Sorted Matrix AC
- LeetCode136.cpp Single Number AC hash table
- LeetCode260.cpp Single Number III AC
- LeetCode387.cpp First Unique Character in a String AC
- LeetCode23.cpp Merge k Sorted Lists O(nlogk) AC
- LeetCode1046.cpp Last Stone Weight AC
- dijkstra_heap.cpp
- queue
- SimulateQueue.cpp
- LeetCode102.cpp Binary Tree Level Order Traversal AC
- LeetCode107.cpp Binary Tree Level Order Traversal II AC
- LeetCode637.cpp Average of Levels in Binary Tree AC
- LeetCode429.cpp N-ary Tree Level Order Traversal AC
- monotonous queue
- LeetCode239.cpp Sliding Window Maximum AC monotonous stack
- JZ64.cpp
- NowCoder1006D.cpp
- deque
- Linked List
- SimulateLinkedList.cpp AC UVa Data Structure
- LeetCode21.cpp Merge Two Sorted Lists AC
- LeetCode460.cpp Flatten a Multilevel Doubly Linked List AC
- LeetCode83.cpp Remove Duplicates from Sorted List AC
- LeetCode2095.cpp Delete the Middle Node of a Linked List AC
- LeetCode66.cpp Plus One AC
- LeetCode61.cpp Rotate List AC
- LeetCode86.cpp Partition List AC
- Reverse Linked List
- LeetCode203.cpp Remove Linked List Elements AC
- LeetCode19.cpp Remove Nth Node From End of List O(2n) two pass algorithms AC
- LeetCode234.cpp Palindrome Linked List AC
- Sort List
- LeetCode445.cpp Add Two Numbers II AC
- LeetCode83.cpp Remove Duplicates from Sorted List AC
- LeetCode707.cpp Design Linked List AC
- LeetCode1721.cpp Swapping Nodes in a Linked List AC
- LeetCode160.cpp Intersection of Two Linked Lists AC
- LeetCode543.cpp Diameter of Binary Tree AC
- LRU/LFU
- LeetCode1290.cpp Convert Binary Number in a Linked List to Integer AC
- LeetCode328.cpp Odd Even Linked List AC
- Bloom Filter
- stack
- SimulateStack.cpp
- LeetCode20.cpp Valid Parentheses AC
- LeetCode155.cpp Min Stack AC 数组+两个小顶堆实现
- Evaluate Expressions
- monotonous stack
- union find
- LeetCode704.cpp Binary Search AC
- LeetCode33.cpp Search in Rotated Sorted Array AC(binary search) 这四道题目其实延伸出很多题目,比如如何在Rotated Sorted Array中找到最小元素的下标并返回?
- LeetCode69.cpp Sqrt(x) AC
- LeetCode367.cpp Valid Perfect Square AC
- LeetCode278.cpp First Bad Version AC
- LeetCode34.cpp Find First and Last Position of Element in Sorted Array AC
- LeetCode374.cpp Guess Number Higher or Lower AC
- LeetCode162.cpp Find Peak Element AC
- LeetCode852.cpp Peak Index in a Mountain Array AC
- LeetCode287.cpp Find the Duplicate Number Binary Search AC interesting problem
- LeetCode35.cpp Search Insert Position AC
- LeetCode744.cpp Find Smallest Letter Greater Than Target AC(binary search)
- JZ32.cpp 数字在排序数组中出现的次数 AC
- LeetCode215.cpp Kth Largest Element in an Array binary search O(n)时间复杂度 O(1)空间复杂度,比heap更省空间
- LeetCode378.cpp Kth Smallest Element in a Sorted Matrix AC binary search 思路同LeetCode215.cpp
- LeetCode167.cpp Two Sum II - Input array is sorted binary search
- LeetCode540.cpp Single Element in a Sorted Array AC
- LeetCode349.cpp Intersection of Two Arrays O(n) AC
- LeetCode74.cpp Search a 2D Matrix AC nlogn
- LeetCode653.cpp Two Sum IV - Input is a BST AC binary search 树形结构二分
- LeetCode230.cpp Kth Smallest Element in a BST AC (binary search & in-order traversal)
- LeetCode719.cpp Find K-th Smallest Pair Distance (单纯的使用binary search 或者 heap均 TLE Hard),其中binary search的方法和leetcode 215思路一致
- LeetCode786.cpp K-th Smallest Prime Fraction (单纯的使用binary search 或者 heap均 TLE Hard)
- LeetCode658.cpp Find K Closest Elements AC
- LeetCode1200.cpp Minimum Absolute Difference AC Binary search
- LeetCode275.cpp H-Index II AC
- In-order travel
- BST
- BST basic operations
- LeetCode109.cpp Convert Sorted List to Binary Search Tree AC
- LeetCode701.cpp Insert into a Binary Search Tree AC
- LeetCode450.cpp Delete Node in a BST AC
- LeetCode700.cpp Search in a Binary Search Tree AC
- LeetCode98.cpp Validate Binary Search Tree AC
- LeetCode958.cpp Check Completeness of a Binary Tree AC
- LeetCode230.cpp Kth Smallest Element in a BST AC
- LeetCode653.cpp Two Sum IV - Input is a BST AC
- LeetCode938.cpp Range Sum of BST AC
- LeetCode173.cpp Binary Search Tree Iterator AC
- LeetCode530.cpp Minimum Absolute Difference in BST AC
- LeetCode783.cpp Minimum Distance Between BST Nodes AC
- LeetCode501.cpp Find Mode in Binary Search Tree AC
- LeetCode99.cpp Recover Binary Search Tree AC
- LeetCode285.cpp Inorder Successor In BST AC
- Lowest Common Ancestor (LCA)
- Pre-order travel
- LeetCode257.cpp Binary Tree Paths AC
- LeetCode129.cpp Sum Root to Leaf Numbers AC
- LeetCode144.cpp Binary Tree Preorder Traversal AC
- LeetCode589.cpp N-ary Tree Preorder Traversal AC
- LeetCode671.cpp Second Minimum Node In a Binary Tree AC
- LeetCode1022.cpp Sum of Root To Leaf Binary Numbers
- LeetCode111.cpp Minimum Depth of Binary Tree AC
- LeetCode112.cpp Path Sum AC
- LeetCode113.cpp Path Sum II AC
- LeetCode563.cpp Binary Tree Tilt AC
- LeetCode572.cpp Subtree of Another Tree AC
- Post-order travel
- Level-order travel
- LeetCode102.cpp Binary Tree Level Order Traversal AC
- LeetCode662.cpp Maximum Width of Binary Tree AC
- LeetCode107.cpp Binary Tree Level Order Traversal II AC
- LeetCode116.cpp Populating Next Right Pointers in Each Node AC
- LeetCode117.cpp Populating Next Right Pointers in Each Node II AC
- LeetCode958.cpp Check Completeness of a Binary Tree AC
- LeetCode637.cpp Average of Levels in Binary Tree AC
- LeetCode429.cpp N-ary Tree Level Order Traversal AC
- LeetCode222.cpp Count Complete Tree Nodes AC
- LeetCode1161.cpp Maximum Level Sum of a Binary Tree AC
- LeetCode104.cpp Maximum Depth of Binary Tree AC
- LeetCode559.cpp Maximum Depth of N-ary Tree AC
- LeetCode965.cpp Univalued Binary Tree AC
- LeetCode513.cpp Find Bottom Left Tree Value AC
- LeetCode515.cpp Find Largest Value in Each Tree Row AC
- leetCode103.cpp Binary Tree Zigzag Level Order Traversal AC
- Recursion
- LeetCode226.cpp Invert Binary Tree AC
- LeetCode404.cpp Sum of Left Leaves AC
- LeetCode1305.cpp All Elements in Two Binary Search Trees AC
- LeetCode1302.cpp Deepest Leaves Sum AC
- LeetCode100.cpp Same Tree AC
- LeetCode114.cpp Flatten Binary Tree to Linked List AC
- LeetCode101.cpp Symmetric Tree AC
- LeetCode872.cpp Leaf-Similar Trees AC
- LeetCode110.cpp Balanced Binary Tree AC
- LeetCode508.cpp Most Frequent Subtree Sum AC
- Construction Tree
- LeetCode108.cpp Convert Sorted Array to Binary Search Tree AC
- LeetCode109.cpp Convert Sorted List to Binary Search Tree AC
- LeetCode1008.cpp Construct Binary Search Tree from Preorder Traversal AC
- LeetCode105.cpp Construct Binary Tree from Preorder and Inorder Traversal AC
- LeetCode106.cpp Construct Binary Tree from Inorder and Postorder Traversal AC
- LeetCode889.cpp Construct Binary Tree from Preorder and Postorder Traversal AC
- LeetCode17.cpp Letter Combinations of a Phone Number AC
- Serialize and Deserialize
- DFS
- Morris travel
- LeetCodeGraphTraversalTemplate.cpp 图的DFS和BFS模板,保存图时采用了邻接列表的方式,不用邻接矩阵(浪费空间和时间)
- DFS
- Topology Sort
- Shortest Path
- MST
- Network Flow
- bipartite graph
- 最大可行流 (简称最大流,定义参加算法导论中流网络部分)
最短路径类型 | 算法 | 时间复杂度 | 算法类型 |
---|---|---|---|
边权均为正,单源最短路径,稠密图 | 朴素dijkstra | O(n^2) | 贪心 |
边权均为正,单源最短路径,稀疏图 | heap+dijkstra | O(mlogn) | 贪心 |
边权存在负值,单源最短路径,限制最短路径<=k | bellman-ford | O(nm) | 离散数学、动态规划 |
边权存在负值,单源最短路径, 不限制 | SPFA | 平均情况下为O(m),最坏O(nm) | BFS优化bellman-ford |
多源(起点)汇(终点)最短路径 | floyd | O(n^3) | 动态规划 |
最小生成树类型 | 算法 | 时间复杂度 | 算法类型 |
---|---|---|---|
稠密图 | 朴素prim | O(n^2) | 贪心 |
稀疏图 | heap+prim | O(mlogn) | 贪心 |
稀疏图 | kruskal | O(mlogm) | 贪心 |
注意:如果点数n和边数m在同一个数量级为稀疏图,如果m和n^2在一个数量级,则该图为稠密图。
- LeetCode384.cpp Shuffle an Array AC
- LeetCode382.cpp Linked List Random Node AC
- LeetCode398.cpp Random Pick Index AC
- LeetCode710.cpp Random Pick with Blacklist AC
- SQL solutions
- LeetCode175.sql Combine Two Tables AC
- find kth elements
- LeetCode196.sql Delete Duplicate Emails AC
- LeetCode197.sql Rising Temperature AC
- LeetCode620.sql AC
- LeetCode626.sql AC
- LeetCode595.sql Big Countries AC
- LeetCode596.sql Classes More Than 5 Students AC
- LeetCode627.sql Swap Salary AC
- QS.sql
- 统计参数,其中均值,最大值,最小值,平均值,计数都有内置的聚集函数
- LeetCode1114.cpp
- LeetCode1115.cpp
- LeetCode1116.cpp
- LeetCode1117.cpp
- LeetCode1195.cpp
- LeetCode1226.cpp
- CUDA Programming
- Thread-Parallel-Programming
- Concurrent Data Structure
- 背包型
- 一定要注意背包问题初始化的含义,何时为0,何时为INF,何时为-INF;其次要注意f[i]到含义是<=i还是=i,这与初始化有关
- 背包模型参见dd大神的github https://github.com/tianyicui/DP-Book
- 0-1背包问题
- 完全背包问题
- 多重背包问题
- 混合背包问题
- 分组背包问题
- 二维费用的背包问题
- 背包问题求具体方案
- 有依赖的背包裸题模板
- 线性DP
- 定义:递推关系存在一个近似的线性关系,我们就称为线性DP,区别于树形DP.其实不需要严格地将DP分型。
- triangleDP.cpp 数字三角形
- LeetCode322.cpp Coin Change AC
- LeetCode62.cpp Unique Paths AC
- NOI1287.cpp 最低通行费 AC
- LeetCode64.cpp Minimum Path Sum AC
- P1004_luogu.cpp 方格取数 AC
- P1006_luogu.cpp 传纸条 AC
- LeetCode741.cpp Cherry Pickup AC
- LeetCode152.cpp Maximum Product Subarray AC
- LeetCode10.cpp Regular Expression Matching AC
- LeetCode55.cpp Jump Game DP(AC) greedy(AC)
- LeetCode70.cpp Climbing Stairs AC
- LeetCode509.cpp Fibonacci Number AC
- 最长上升子序列(LIS)
- 求LIS的长度
- 求一个LIS的解 (同求LIS的长度,只要在其上稍加变形即可)
- 求LIS的个数
- 求所有LIS的解
- Edit Distance
- 最长公共子序列 (LCS)
- 区间DP
- 计数型
- 数位统计型
- 状态压缩型
- [蒙德里安的梦想 状态压缩的经典应用]
- 树形DP
- 状态机模型
- DP优化方法
- 单调队列优化DP
- 斜率优化DP
- 记忆化搜索(DP问题递归写法的学名,属于DP的一种实现方法)
- LeetCode55.cpp Jump Game 存在一个greedy的解 AC
- LeetCode452.cpp Minimum Number of Arrows to Burst Balloons AC sort+greedy求相邻区间的交集
- LeetCode11.cpp Container With Most Water AC 相向型指针
- 区间问题
- LeetCode56.cpp Merge Intervals AC sort+greedy
- LeetCode57.cpp Insert Interval AC sort+greedy给出了两种方法,都能AC
- LeetCode986.cpp Interval List Intersections AC merge的部分实际上和mergesort中的merge有异曲同工之处
- LeetCode435.cpp Non-overlapping Intervals AC sort+greedy method
- LeetCode1288.cpp Remove Covered Intervals AC sort+greedy
- interval.cpp 区间选点 AC
- intervalGroup.cpp 区间分组
- intervalCover.cpp 区间覆盖
- huffman tree
- 排序不等式
- 绝对值不等式
- DFS + Backtrack
- LeetCode17.cpp Letter Combinations of a Phone Number AC
- LeetCode39.cpp Combination Sum AC
- LeetCode40. Combination Sum II AC
- LeetCode216. Combination Sum III AC
- LeetCode46.cpp Permutations AC
- LeetCode47.cpp Permutations II AC 先排序去重
- POJ1256.cpp AC 先排序去重
- LeetCode78.cpp Subsets AC
- LeetCode90.cpp Subsets II AC
- LeetCode77. Combinations AC
- LeetCode79.cpp Word Search AC
- LeetCode60.cpp Permutation Sequence AC
- LeetCode1286.cpp Iterator for Combination AC
- LeetCode51.cpp N-Queens I AC
- LeetCode52.cpp N-Queens II AC
- LeetCode22.cpp Generate Parentheses AC
- BFS + Branch-and-Bound
method | extra space | priorities | Data Structure |
---|---|---|---|
DFS | O(h) | 无 | stack |
BFS | O(2^h) | shortest path(权重必须为1,否则不能找到最短路径)、topology sort | queue |
- LeetCode493.cpp Reverse Pairs AC
- LeetCode98.cpp Validate Binary Search Tree AC 简单但不失优雅
- LeetCode4.cpp Median of Two Sorted Arrays AC
- LeetCode509.cpp Fibonacci Number AC
- Permutation 本题是一个Generation in lexicographic order,具体见链接 https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
- LeetCode31.cpp Next Permutation AC
- LeetCode46.cpp Permutations AC 调用了LeetCode31.cpp的Next Permutation函数
- LeetCode47.cpp Permutations II AC 和LeetCode46.cpp代码完全一样
- LeetCode60.cpp Permutation Sequence AC LeetCode31.cpp变形题
- 说明:这四道题目中,采用了三种方法:wiki 方法、C++ STL next_permutation、DFS 搜索方法,其中 DFS 搜索只能用在没有重复元素的情况下,如果存在重复元素 DFS 会生成重复序列,除非想办法进行特殊判断,因此在有重复元素的情况下,只能采用 C++ STL next_permutation 方法和 wiki 方法来做。C++ STL next_permutation 方法库中的实现采用了 wiki 方法,这样的封装使得 permutation 问题变得更加简洁。
int cal(int n) {
int sum = 0;
int i = 1;
for (; i <= n; ++i) {
sum = sum + i;
}
return sum;
}
如上述代码,在上述代码中,只有for循环中的sum+=i
被执行了
在时空复杂度分析中,有下面三个法则:
- 只关注循环执行次数最多的一段代码
- 加法法则:总复杂度等于量级最大的那段代码的复杂度,该法则适用于多段平行代码段,总的时间复杂度为最大
- 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
4.1 节讲了基本的时间复杂度表示方法,本节将重点讲述最好、最坏、平均、均摊时间复杂度分析,这样便有了完整的时间复杂度分析方法。
// n 表示数组 array 的长度
int find(int[] array, int n, int x) {
int i = 0;
int pos = -1;
for (; i < n; ++i) {
if (array[i] == x) pos = i;
}
return pos;
}
上述代码的时间复杂度为
// n 表示数组 array 的长度
int find(int[] array, int n, int x) {
int i = 0;
int pos = -1;
for (; i < n; ++i) {
if (array[i] == x) {
pos = i;
break;
}
}
return pos;
}
如上代码,在最好情况下:数组的首元素的值与x相等,此时时间复杂度为
上述值就是每个位置可能出现等于x的情况的加权平均值,也叫做期望值,所以平均时间复杂度的全称应该叫做加权平均时间复杂度或者期望时间复杂度。上述值用大
这种分析方法没有考虑每种情况出现的概率,不可取。
上述两节之后我们已经初步掌握了时间复杂度的分析方法,本节介绍均摊时间复杂度,均摊时间复杂度对应于算法中的摊还分析(或者叫平摊分析)。相比最好、最差、平均时间复杂度,均摊时间复杂度的使用场景更加特殊、更加有限。
// array 表示一个长度为 n 的数组
// 代码中的 array.length 就等于 n
int[] array = new int[n];
int count = 0;
void insert(int val) {
if (count == array.length) {
int sum = 0;
for (int i = 0; i < array.length; ++i) {
sum = sum + array[i];
}
array[0] = sum;
count = 1;
}
array[count] = val;
++count;
}
这段代码实现了往数组中插入数据的功能。当数组满了之后,也就是代码中 count==array.length 时,通过 for 循环遍历数组求和,并清空数组,将求和之后的 sum 值放到数组的第一个位置,然后再将心得数据插入。当数组一开始有空闲位置时,则直接将数据插入数组。
最好情况下时间复杂度
最坏情况下时间复杂度
平均时间复杂度
到目前位置,最好情况下时间复杂度、最坏情况下时间复杂度、平均情况下时间复杂度的计算,理解起来都没有任何问题。但是这个例子的平均复杂度分析其实并不需要上述那样复杂,不需要引入概率论的知识。这是为什么呢?其实将本例的insert()和前面的find()进行对比,可以知道,find()函数在极端情况下复杂度才为
我们还是继续看在数组中插入数据的例子。每一次
对一个数据结构进行的操作中,大部分情况下时间复杂度都很低,只有个别情况下时间复杂度比较高,而且这些操作之间存在前后连贯的时序关系,这个时候,我们就可以将这一组操作放在一块儿分析,看是否能够将较高时间复杂度的那次操作的耗时平摊到其它时间复杂度较低的操作上。而且,在能够应用平摊时间复杂度的分析场景中,一般均摊时间复杂度就等于最好情况下的时间复杂度。
尽管许多数据结构和算法书籍都花了很大的力气来区分平均时间复杂度和均摊时间复杂度,但是其实我认为,均摊时间复杂度就是一种特殊的平均时间复杂度,我们没必要花太多的精力去区分它们。我们应该花时间去掌握它的分析方法,摊还分析法。至于分析出来的结果叫平均还是均摊,并不重要。
之所以引入最好时间复杂度、最坏时间复杂度、平均时间复杂度、均摊时间复杂度这些概念,是因为很多算法,在不同的输入情况下,算法的时间复杂度不一样。在引入这些概念以后,我们能够更加全面的表示算法的时间复杂度。
// 全局变量,大小为 10 的数组 array,长度 len,下标 i。
int array[] = new int[10];
int len = 10;
int i = 0;
// 往数组中添加一个元素
void add(int element) {
if (i >= len) { // 数组空间不够了
// 重新申请一个 2 倍大小的数组空间
int new_array[] = new int[len*2];
// 把原来 array 数组中的数据依次 copy 到 new_array
for (int j = 0; j < len; ++j) {
new_array[j] = array[j];
}
// new_array 复制给 array,array 现在大小就是 2 倍 len 了
array = new_array;
len = 2 * len;
}
// 将 element 放到下标为 i 的位置,下标 i 加一
array[i] = element;
++i;
}
/*答案:
最好时间复杂度O(1),最坏时间复杂度O(n),平均时间复杂度O(1),均摊时间复杂度为O(1)
假设数组的长度为n,当数组未满时,每次往数组中添加元素的时间复杂度都为O(1),当数组满时,需要O(n)的操作进行复制,并且这两个操作具有严格的时序关系,因此可以将复制的操作摊还给前面n-1次操作中,最终得到的时间复杂度仍然为O(1)
平均时间复杂度计算:
1 * 1/(n+1) + 1 * 1/(n+1) ... + n * 1/(n+1) = O(1)
*/
- http://www.cs.cmu.edu/~anupamg/advalgos15/
- http://speech.ee.ntu.edu.tw/~tlkagk/courses_ML20.html
- http://erikdemaine.org/classes/
- SQL练习 https://www.hackerrank.com/domains/sql (随机写题) https://sqlzoo.net/ (有针对性地练习SQL的方方面面特性)
- 50道必须会的SQL题目 https://www.techbeamers.com/sql-query-questions-answers-for-practice/
- https://www.techbeamers.com/top-sql-interview-questions-dba-qa/
- ACM刷题题单
更多信息参见协议文件。