線性數據結構 - Queue、Stack、Hash
樹型數據結構 - Heap / Priority Queue、TreeMap
BFS的主要數據結構是 Queue
DFS的主要數據結構是 Stack
目錄:
-
- 什麼是數據結構
1.1 分類
1.2 什麼是數據結構?
- 什麼是數據結構
-
- 隊列 Queue
2.1 基礎知識
2.2 相關題目 - BFS相關的題目
- 隊列 Queue
-
- 棧 Stack
3.1 基礎知識
3.2 相關題目 - 非遞歸實現DFS的主要數據結構
3.3 min-stack 帶最小值操作的棧(12 in lintcode)
3.4 largest-rectangle-in-histogram 直方圖最大矩陣覆蓋(122 in lintcode)
3.5 maximal-rectangle 最大矩陣(510 in lintcode)
- 棧 Stack
-
- 哈希表 Hash - 見相關筆記
-
- 樹型數據結構 - 見相關筆記,包括Heap / Priority Queue、TreeMap
1. 什麼是數據結構 -
1.1 分類
1.2 什麼是數據結構?
1). 數據結構 = 集合 + 集合上的若干操作
2). 可以在鏈表上進行二分法嗎?
不可以,因爲二分法複雜度爲O(n),(O(n) = O(n/2) + O(1)) O(1)鏈表不能達到
3). 定義一種數據結構,必須要定義該數據結構支持的操作,以及操作的時間複雜度是什麼
4). 所有的數據結構落實到底層數據結構均爲2種:
- 數組(連續空間)
- 鏈表(離散空間)
2. 隊列 Queue -
2.1 基礎知識
1). 先進先出。
2). 支持的操作: O(1) Push / O(1) Pop / O(1) Top
3). BFS的主要數據結構。多做BFS的題目就可以了。
4). 實現隊列的話,數組和鏈表均可,linkedList更常用,c++中的vector、java中的ArrayList,是動態數組,每次空間不夠時乘2。還可以使用循環數組實現隊列。
5). 建議用數組和鏈表把隊列都實現一遍。
2.2 相關題目 - BFS相關的題目
3. 棧 Stack - 非遞歸實現DFS的主要數據結構
3.1 基礎知識
1). 後進先出,在末尾操作
2). 支持的操作: O(1) Push / O(1) Pop / O(1) Top
3). DFS非遞歸實現的主要數據結構。多做BFS的題目就可以了。
4). 建議用數組和鏈表把隊列都實現一遍。
3.2 相關題目 - 非遞歸實現DFS的主要數據結構
3.3 min-stack 帶最小值操作的棧(12 in lintcode)
1.題目
http://www.lintcode.com/zh-cn/problem/min-stack/
http://www.jiuzhang.com/solution/min-stack/
實現一個帶有取最小值min方法的棧,min方法將返回當前棧中的最小值。
你實現的棧將支持push,pop 和 min 操作,所有操作要求都在O(1)時間內完成。
樣例
如下操作:push(1),pop(),push(2),push(3),min(), push(1),min() 返回 1,2,1
2.代碼
1). 典型的數據結構的實現題
2). 分析:
2個stack,保存最小值得變化序列。每次push、pop時,需要更新存最小值的棧。
3). 代碼
3.4 largest-rectangle-in-histogram 直方圖最大矩陣覆蓋(122 in lintcode)
1.題目
http://www.lintcode.com/zh-cn/problem/largest-rectangle-in-histogram/
http://www.jiuzhang.com/solution/largest-rectangle-in-histogram/
Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
The largest rectangle is shown in the shaded area, which has area = 10 unit.
樣例
給出 height = [2,1,5,6,2,3],返回 10
2.思路 &代碼
1). 分析:
最多有n2種組合,理論上複雜度可以降到n2。
如果複雜度爲多項式(n^2 ,n3,n4… ),則一定不用dp,dp適合複雜度爲2^n的。
2). 求解
解法1:-時間複雜度O(n^2),會超時 TLE
A.兩個for循環,startIndex,endIndex。
挪動endIndex時,記錄最小值,並將計算到的面積與全局面積比較。
B. 出現TLE的可能情況
- 複雜度太高;
- 死循環 (如二分法或者鏈表等複雜度不高的元素出現超時,一定是死循環了)
解法2:- O(n)
A. nlogn的可能算法有以下三種:
- Divide & Conqure, O(n) 分爲2部分,遞歸,如merge sort
- 先排序,再用O(n)搞定
- for一遍,內部支持logn的數據結構,如heap/priority queue / TreeMap 求最大最小值
B. 本題使用 單調棧,複雜度是O(n)
- 單調棧可以找到某個數左邊(右邊)第一個比他小的數
3.5 maximal-rectangle 最大矩陣(510 in lintcode)
1.題目
http://www.lintcode.com/zh-cn/problem/maximal-rectangle/
http://www.jiuzhang.com/solution/maximal-rectangle/
給你一個二維矩陣,權值爲False和True,找到一個最大的矩形,使得裏面的值全部爲True,輸出它的面積
樣例
給你一個矩陣如下
[
[1, 1, 0, 0, 1],
[0, 1, 0, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1]
]
輸出6
2.思路 & 代碼
此題是之前那道的 Largest Rectangle in Histogram 直方圖中最大的矩形 的擴展,這道題的二維矩陣每一層向上都可以看做一個直方圖,輸入矩陣有多少行,就可以形成多少個直方圖,對每個直方圖都調用 Largest Rectangle in Histogram 直方圖中最大的矩形 中的方法,就可以得到最大的矩形面積。那麼這道題唯一要做的就是將每一層構成直方圖,由於題目限定了輸入矩陣的字符只有 ‘0’ 和 ‘1’ 兩種,所以處理起來也相對簡單。方法是,對於每一個點,如果是‘0’,則賦0,如果是 ‘1’,就賦 之前的height值加上1。具體參見代碼如下:
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if (matrix.empty() || matrix[0].empty()) return 0;
int res = 0, m = matrix.size(), n = matrix[0].size();
vector<int> height(n + 1, 0);
for (int i = 0; i < m; ++i) {
stack<int> s;
for (int j = 0; j < n + 1; ++j) {
if (j < n) {
height[j] = matrix[i][j] == '1' ? height[j] + 1 : 0;
}
while (!s.empty() && height[s.top()] >= height[j]) {
int cur = s.top(); s.pop();
res = max(res, height[cur] * (s.empty() ? j : (j - s.top() - 1)));
}
s.push(j);
}
}
return res;
}
};