• 【C++】搜索二叉树面试oj题


    1.根据二叉树创建字符串 

    链接:根据二叉树创建字符串:力扣

      

     

    解析:题目是按照前序遍历根,左子树,右子树的遍历方式来存储节点值的。

    1(左)(右) ->1((左)(右))((左)(右))。第一种情况不说了,看第二种情况,2的左子树为空,又又子数,但是他的左子树的括号不能省略,你要是省略了就不知道这个4是他的左子树还是右子树。

    1. class Solution {
    2. public:
    3. string tree2str(TreeNode* root) {
    4. if(root==nullptr)
    5. return string();
    6. //空树就返回一个空的string对象就可以了
    7. string str;
    8. str+=to_string(root->val); //根
    9. str+="("; //左子树
    10. str+=tree2str(root->left);
    11. str+=")";
    12. str+="("; //右子树
    13. str+=tree2str(root->right);
    14. str+=")";
    15. return str;
    16. }
    17. };

    to_string函数是专门让将数字常量转换为字符串,返回值为转换完毕的字符串。

    但是这个还不算完,因为这样我们把所有的括号都打印了,该省去的都打印出来了。

    • 啥时候省略?

    对于左子树来说,左空右空省括号,左空右有(右子树还有数值)不能省,所以只要右子树是空就一定省去括号。

    1. class Solution {
    2. public:
    3. string tree2str(TreeNode* root) {
    4. if(root==nullptr)
    5. return string();
    6. string str;
    7. str+=to_string(root->val);
    8. if(root->left||root->right)
    9. {
    10. str+="(";
    11. str+=tree2str(root->left);
    12. str+=")";
    13. }
    14. if(root->right)
    15. {
    16. str+="(";
    17. str+=tree2str(root->right);
    18. str+=")";
    19. }
    20. return str;
    21. }
    22. };

     2.二叉树分层遍历

    二叉树的分层遍历1:力扣 

    其实这个用队列解决特别爽,先放根进去,然后放左右子树进去,再把根取出队列,再放进去第三代,然后取出第二代。

    但是这个有一个疑问,就比如我们取出根后第二三代都在队列中,咋判断这些数是第二代的还是第三代的?

    这里我们用levelSize来记录每一代的个数,那这样即使隔代也能正确出队列了。

    1. class Solution {
    2. public:
    3. vectorint>> levelOrder(TreeNode* root) {
    4. queue q; //创建一个队列
    5. size_t levelSize=0; //记录每一层的实节点个数
    6. if(root) //根不为空,进队列
    7. {
    8. q.push(root);
    9. levelSize=1; // 记录第一代的个数
    10. }
    11. vectorint>> vv;
    12. while(!q.empty())
    13. {
    14. vector<int> v;
    15. for(int i=0;i
    16. {
    17. TreeNode* front=q.front();
    18. q.pop();
    19. v.push_back(front->val);
    20. if(front->left)
    21. {
    22. q.push(front->left);
    23. }
    24. if(front->right)
    25. {
    26. q.push(front->right);
    27. }
    28. }
    29. vv.push_back(v);
    30. levelSize=q.size();
    31. }
    32. return vv;
    33. }
    34. };
    • vv:创造的一个二维数组,用来存放二叉树的数据的,他的每一行就是每一代。
    • v:  一维数组,在这个循环里是用来存放每一代的数据的。
    • front:用来保存每一个出队列后的数值。
    • 当把每一行都给vv之后,改变levelSize使他记录的是下一代的个数。

    3.最近公共祖先 

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先:力扣 

     这个题会遇到这三种情况;

    p,q分别在根的两边;都在左边;都在右边。

    1. class Solution {
    2. bool Find(TreeNode* sub, TreeNode* x) //查找p,q到底在哪一边
    3. {
    4. if(sub==nullptr)
    5. {
    6. return false;
    7. }
    8. if(sub==x) //找到了
    9. {
    10. return true;
    11. }
    12. return Find(sub->left,x)||Find(sub->right, x);
    13. }
    14. public:
    15. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
    16. {
    17. if (root==nullptr)
    18. {
    19. return nullptr;
    20. }
    21. if(root==p||root==q)
    22. {
    23. return root;
    24. }
    25. bool pleft,pright,qleft,qright;
    26. //分别判断p,q到底在哪一边
    27. pleft=Find(root->left, p);
    28. pright=!pleft;
    29. qleft=Find(root->left,q);
    30. qright=!qleft;
    31. //1.p,q在两边
    32. //2.p,q都在左边
    33. //3.p,q都在右边
    34. if((qleft&&pright)||(qright&&pleft))
    35. {
    36. return root;
    37. }
    38. else if(qleft&&pleft)
    39. {
    40. return lowestCommonAncestor(root->left,p,q);
    41. }
    42. else if(qright&&pright)
    43. {
    44. return lowestCommonAncestor(root->right,p,q);
    45. }
    46. else //这种情况一般都走不到
    47. {
    48. return nullptr;
    49. }
    50. }
    51. };

    这里的精髓是pleft,pright,qleft,qright。

    举个例子,如果p在左子树,那pright就不用找了,如果左子树上没找到,那他一定在右子树那里。

     

  • 相关阅读:
    TCP三次握手与四次挥手详解
    Java Stream流对List集合进行分页
    Python超入门(5)__迅速上手操作掌握Python
    IT运维管理平台助力企业打造监、管、控一体化
    使用element-ui导航,进入对应的三级页面菜单保持点击状态
    JVM虚拟机-虚拟机性能监控、故障处理工具
    搭建RabbitMQ消息服务,整合SpringBoot实现收发消息
    蓝桥杯算法题——暴力枚举法
    HTTP 面试知识点提炼
    【WINDOWS / DOS 批处理】IF命令之比较运算符证明实例
  • 原文地址:https://blog.csdn.net/bit_jie/article/details/127668345