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