File tree Expand file tree Collapse file tree 3 files changed +101
-8
lines changed Expand file tree Collapse file tree 3 files changed +101
-8
lines changed Original file line number Diff line number Diff line change 7474
7575*  二叉树经典题目 
7676
77- 
78- (待补充.....)
77+ (补充ing)
7978
8079# 算法模板   
8180
82- ## 二分法   
83- (待补充....)
81+ ## 二分查找法   
82+ 
83+ ``` 
84+ class Solution { 
85+ public: 
86+  int searchInsert(vector<int>& nums, int target) { 
87+  int n = nums.size(); 
88+  int left = 0; 
89+  int right = n; // 我们定义target在左闭右开的区间里,[left, right)  
90+  while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间 
91+  int middle = left + ((right - left) >> 1); 
92+  if (nums[middle] > target) { 
93+  right = middle; // target 在左区间,因为是左闭右开的区间,nums[middle]一定不是我们的目标值,所以right = middle,在[left, middle)中继续寻找目标值 
94+  } else if (nums[middle] < target) { 
95+  left = middle + 1; // target 在右区间,在 [middle+1, right)中 
96+  } else { // nums[middle] == target 
97+  return middle; // 数组中找到目标值的情况,直接返回下标 
98+  } 
99+  } 
100+  return right; 
101+  } 
102+ }; 
103+ 
104+ ``` 
84105
85106## KMP  
86107
87- (待补充....)
108+ ``` 
109+ void kmp(int* next, const string& s){ 
110+  next[0] = -1; 
111+  int j = -1; 
112+  for(int i = 1; i < s.size(); i++){ 
113+  while (j >= 0 && s[i] != s[j + 1]) { 
114+  j = next[j]; 
115+  } 
116+  if (s[i] == s[j + 1]) { 
117+  j++; 
118+  } 
119+  next[i] = j; 
120+  } 
121+ } 
122+ ``` 
88123
89124## 二叉树   
90125
@@ -226,8 +261,24 @@ vector<vector<int>> levelOrder(TreeNode* root) {
226261
227262### 二叉树深度  
228263
264+ ``` 
265+ int getDepth(TreeNode* node) { 
266+  if (node == NULL) return 0; 
267+  return 1 + max(getDepth(node->left), getDepth(node->right)); 
268+ } 
269+ ``` 
270+ (补充ing)
271+ 
229272### 二叉树节点数量  
230273
274+ ``` 
275+ int countNodes(TreeNode* root) { 
276+  if (root == NULL) return 0; 
277+  return 1 + countNodes(root->left) + countNodes(root->right); 
278+ } 
279+ ``` 
280+ 
281+ 
231282# LeetCode 最强题解:  
232283
233284| 题目 |  类型 |  难度 |  解题方法 | 
Original file line number Diff line number Diff line change @@ -177,9 +177,7 @@ public:
177177
178178``` 
179179
180- 那么后序遍历呢
181- 
182- 先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序
180+ 再来看后序遍历,先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序
183181,然后在反转result数组,输出的结果顺序就是左右中了,如下图:
184182![ 前序到后序] ( https://img-blog.csdnimg.cn/20200808200338924.png ) 
185183
@@ -208,8 +206,52 @@ public:
208206
209207``` 
210208
209+ 此时我们实现了前后中遍历的三种迭代法,是不是发现迭代法实现的先中后序,其实风格也不是那么统一,除了先序和后序,有关联,中序完全就是另一个风格了,一会用栈遍历,一会又用指针来遍历。
210+ 
211+ 重头戏来了,接下来介绍一下统一写法。
212+ 
213+ #### 迭代法统一写法  
214+ 
215+ 我们以中序遍历为例,之前说使用栈的话,** 无法同时解决处理过程和访问过程不一致的情况** ,那我们就将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记,标记就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。
216+ 
217+ 代码如下:
218+ ``` 
219+ class Solution { 
220+ public: 
221+  vector<int> inorderTraversal(TreeNode* root) { 
222+  vector<int> result; 
223+  stack<TreeNode*> st; 
224+  if (root != NULL) st.push(root); 
225+  while (!st.empty()) { 
226+  TreeNode* node = st.top(); 
227+  if (node != NULL) { 
228+  st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中 
229+  if (node->right) st.push(node->right); // 添加右节点 
230+ 
231+  st.push(node); // 添加中节点 
232+  st.push(NULL); // 中节点访问过,但是还没有处理,需要做一下标记。 
233+ 
234+  if (node->left) st.push(node->left); // 添加左节点 
235+  } else { 
236+  st.pop(); // 将空节点弹出 
237+  node = st.top(); // 重新取出栈中元素 
238+  st.pop(); 
239+  result.push_back(node->val); // 加入到数组中 
240+  } 
241+  } 
242+  return result; 
243+  } 
244+ }; 
245+ ``` 
246+ 
247+ 看代码有点抽象我们来看一下动画:
248+ 
249+ <video  src =' ../video/中序遍历迭代(统一写法).mp4 '  controls =' controls '  width =' 640 '  height =' 320 '  autoplay =' autoplay ' > Your browser does not support the video tag.</video ></div >
250+ 
211251
252+ 大家在看一下具体代码实现
212253
254+ 接下来给大家介绍一种统一的写法。
213255
214256我们再来看一下代码。
215257## C++代码  
                                 You can’t perform that action at this time. 
               
                  
0 commit comments