二叉树题目*公共祖先**后继节点**折纸问题*

目录

二叉树的公共祖先节点:

找到一个节点X的后继节点(中序遍历中一个节点的下一个节点)

折纸问题:


二叉树的公共祖先节点:

236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)icon-default.png?t=N7T8https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

方法1:

1: 首先建立一张哈希表记录全图的父子关系,子为索引,对应的为父。

2: 根据上面建立的哈希表建立关于节点1的“族谱”

3: 根据节点2不断向上推,查找判断节点2的长辈是否在节点1的族谱中,同时因为节点2的寻祖过程是一次向上推的所以找到的一定是两个节点的最近公共祖先。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
void sonAndFather(TreeNode *root,unordered_map<TreeNode*,TreeNode*>&hashtable){
    if(root==NULL||(root->left==NULL&&root->right==NULL)){return;}
    if(root->left!=NULL){hashtable[root->left]=root;sonAndFather(root->left,hashtable);}
    if(root->right!=NULL){hashtable[root->right]=root;sonAndFather(root->right,hashtable);}
    return;
}

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
      unordered_map<TreeNode*,TreeNode*>hashtable; 
      sonAndFather(root,hashtable);//获得哈希表,索引为儿节点对应值为父节点
      unordered_set<TreeNode*>p1;
      //unordered_set<TreeNode*>q2;
      TreeNode *fp;fp=p;
      while(fp!=root){
          p1.insert(fp);
          fp=hashtable[fp];//转化为父节点
      }p1.insert(root);

      //现在已获得全图的子—父哈希表,以及节点1的父节点族谱
      //对节点2使用全图哈希表,不断获得节点2的长辈,同时在节点1的族谱中寻找判断是否有节点2的长辈

      TreeNode *fq;fq=q;
      while(fq!=root){
          //cout<<fq->val<<" "<<p->val<<endl;
          //if(fq==p){return fq;}
          if(p1.find(fq)!=p1.end()){return fq;}
          fq=hashtable[fq];
          
      }
      return root;
    }
};

方法2:

一个节点向下要信息,如果要信息的过程中碰上了两个个节点中的一个就返回这个碰上的节点。

如果左和右返回的都不是空,那么当前节点就是最近的公共节点(这种情况说明这两个节点是兄弟或叔伯之子的关系)

如果有一侧的返回为空另一侧不为空,说明这两个节点在同一侧并且为直系父子或者爷孙等关系。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //if(root==NULL||root->left==NULL||root->right==NULL){return NULL;}
        if(root==NULL){return NULL;}
        if(root==p){return p;}
        if(root==q){return q;}
        TreeNode *zuo=lowestCommonAncestor(root->left,p,q);
        TreeNode *you=lowestCommonAncestor(root->right,p,q);
        if(zuo!=NULL && you!=NULL){return root;}//兄弟或叔伯侄子关系
        if(zuo!=NULL){return zuo;}//为直系父子或者爷孙等关系
        if(you!=NULL){return you;}//为直系父子或者爷孙等关系
        else{return NULL;}
    }
};

找到一个节点X的后继节点(中序遍历中一个节点的下一个节点)

1:首先判断x有无右树,如果有的话后继节点就是右子树的最左节点。

2:如果无右树,向上找爹,如果该节点无右树且是它爹的左儿子,那么 它爹就是X的后继节点

3:如果无右书,且向上找爹发现X是它爹的右儿子,那么不断向上找,直到发生左儿子找爹的过程,那么这次的爹就是后继节点。

4: 如果找到顶了也就是到了最初始得根节点还没找到,那么后继节点就是null,也就是这种情况下没有后继节点。

折纸问题:

折纸条一次,获得一条折痕为凹

两次,共获得3条折痕,从上到下为凹凹凸

三次,共获得7条折痕,从上到下为凹凹凸凹凹凸凸

给定折纸次数N,请返回折痕结果

利用二叉树,头节点为凹,每个节点的左节点为凹,右节点为凸。最后结果返回该二叉树的中序遍历。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值