赞
踩
今天还是二叉树,刷的是新知识,主要涉及到二叉树的双指针遍历操作。话不多说,直接开始吧!
最原始的思路就是中序遍历搜索二叉树,出来的自然就是一个由小到大的数组,只要比较两个数组之间的值,找出最小的绝对值即可。(此方法会造成O(n)的空间复杂度)
- class Solution {
- private:
- vector<int> res;
- void getMinAbs(TreeNode* root) {
- // 中序遍历出来就是一个升序数组
- if (root == NULL) return;
- getMinAbs(root->left);
- res.push_back(root->val);
- getMinAbs(root->right);
- }
- public:
- int getMinimumDifference(TreeNode* root) {
- int minAbs = INT_MAX;
- getMinAbs(root);
- // 只要敝比较两个相邻的元素,就可以找到
- for (int i = 0; i < res.size() - 1; i++) {
- if ((res[i + 1] - res[i]) < minAbs) {
- minAbs = (res[i + 1] - res[i]);
- }
- }
-
- return minAbs;
- }
- };
这个思路很巧妙,利用的是二叉树上的双指针,来达到此效果。
(1)一个pre指针一个cur指针,pre指针一直指向cur的前一个节点,这实现起来在代码中很巧妙。
(2)一直遍历,一直比较就ok了。
- class Solution {
- private:
- int result = INT_MAX;
- TreeNode* pre;
- void getMinAbs(TreeNode* cur) {
- if (cur == NULL) return;
- getMinAbs(cur->left);
- if (pre != NULL) {
- result = min(result, abs(cur->val - pre->val));
- }
- pre = cur;
- getMinAbs(cur->right);
- }
- public:
- int getMinimumDifference(TreeNode* root) {
- getMinAbs(root);
- return result;
- }
- };
我的第一思路就是递归-统计,找出最大的数,就结束了。
代码如下:
- class Solution {
- private:
- map<int, int> my_map;
- void getMap(TreeNode* root) {
- if (root == NULL) return;
- getMap(root->left);
- my_map[root->val]++;
- getMap(root->right);
- }
-
- public:
- vector<int> findMode(TreeNode* root) {
- int max = INT_MIN;
- getMap(root);
- for (auto it = my_map.begin(); it != my_map.end(); it++) {
- if (max < it->second) max = it->second;
- }
- vector<int> result;
- for (auto it = my_map.begin(); it != my_map.end(); it++) {
- if (max == it->second) result.push_back(it->first);
- }
- return result;
- }
- };
思路二的操作很华丽,也很实用,主要是利用双指针不断维护最大值和统计数以及返回的数组。
总结了以下节点:
(1)创建一个统计和最大的数值,全局变量
(2)利用中序遍历,在中的时候做和第一题差不多的逻辑,并且多加一些功能。
(3)遍历完就可以返回数组了。
- class Solution {
- private:
- int count = 0;
- int maxcount = 0;
- vector<int> result;
- TreeNode* pre;
- void getResult(TreeNode* cur) {
- if (cur == NULL) return;
- getResult(cur->left); // 左
- // 中
- if (pre == NULL) {
- count = 1;
- } else if (pre->val == cur->val) { // 相等就添加累加值
- count++;
- } else { // 不相等就刷新
- count = 1;
- }
- pre = cur;
- if (count == maxcount) {
- result.push_back(cur->val);
- }
- if (count > maxcount) { // 累加大于max,就刷新result
- maxcount = count;
- result.clear();
- result.push_back(cur->val);
- }
- // 右
- getResult(cur->right);
- }
- public:
- vector<int> findMode(TreeNode* root) {
- getResult(root);
- return result;
- }
- };
这个题目首先得了解什么最近公共祖先:
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
举个例子
如果pq使6,5那么7就是公共祖先。
代码的逻辑就是:
后序遍历,左边遍历出p的话就往上返回,一直返回到根节点,返回结果。
比如遍历到10了左为空,有不为空,那就返回右边。
还有一个小的细节,例如p为7,q为5,那么7就是最近祖先,为什么呢?一旦遍历到7,就往上返回了,那么q怎么办?其实这个时候已经知道了q要么在下面,要么在右边,如果是在右边的话,那就是逻辑1了。
- class Solution {
- private:
- TreeNode* findPQ(TreeNode* root, TreeNode* p, TreeNode* q) {
- if (root == NULL) return NULL;
- if (root == p || root == q) return root;
- // 左
- TreeNode* left = findPQ(root->left, p, q);
- // 右
- TreeNode* right = findPQ(root->right, p, q);
- // 中
- if (left != NULL && right != NULL) return root;
- else if (left != NULL && right == NULL) return left;
- else if (left == NULL && right != NULL) return right;
- else return NULL;
- }
- public:
- TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
- return findPQ(root, p, q);
- }
- };
学习时间:2小时
leave message:
He who draws noble delights from sentimets of portry is a true poet, though he never written a line in all his life.
从诗歌情感中汲取高尚快乐的人是真正的诗人,虽然他从未写过诗。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。