力扣270场周赛: 树上节点的共同祖先-记录欧拉路径

欧拉路径的记录


1.

直接枚举

class Solution {
public:
    vector<int> findEvenNumbers(vector<int>& d) {
        // 从给定的所有数字中取出三位偶数,按递增顺序排列
        set<int> ans;

        for(int i=0;i<d.size();i++)
        {
        if(d[i]==0) continue;
            for(int j=0;j<d.size();j++)
            {
                if(i==j) continue ;
                 for(int k=0;k<d.size();k++)
                {   
                    if(i==k||j==k) continue ;
                    int v=d[i]*100+d[j]*10+d[k];
                    ans.insert(v);
                }
            }
        }
               
            
        vector<int> res;
            for(auto it:ans){
                if(it>=100&&it%2==0) res.push_back(it);
            }
        
            return res;
    }
};

2.

https://leetcode-cn.com/problems/delete-the-middle-node-of-a-linked-list/
先预处理出链表长度
剩下的就是链表的基础操作了

class Solution {
public:
    ListNode* deleteMiddle(ListNode* head) {
        if(!head||!head->next) return NULL;
        ListNode *p=head;
        int n=0;
        while(p){
            p=p->next;
            n++;
        }
        p=head;
        n/=2;
        n--;
        while(n--){
            p=p->next;
        }
        p->next=p->next->next;
        return head;
    }
};

3.

寻找树上节点的公共祖先问题
https://leetcode-cn.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/
思路:

  1. 得到从根出发到两节点的路径
  2. 取出公共前缀部分既根节点到公共祖先的路径
  3. 将startVal的路径-公共前缀 剩下的部分全部变为U
  4. 将3获得的结果与endVal的路径-公共前缀拼接即可
 //深搜获取起始节点和终止节点的路径
 //公共前缀就可以获取他俩的共同祖先
 //将起始节点路径在公共前缀后的部分反转(指L->U,R->U)
 // 然后与终止节点拼接即可

class Solution {
public:
 string ans;
 int flag=0;
    void dfs(TreeNode *r,int val,string &temp){
        if(!r) return ;
        if(r->val==val){
            ans=temp;
            flag=1;
            return ;
        }
        if(flag) return ;  // flag用于减枝
        temp+='L';
        dfs(r->left,val,temp);
        temp.pop_back();
        if(flag) return ;
        temp+='R';
        dfs(r->right,val,temp);
        temp.pop_back();
    }


    string getDirections(TreeNode* root, int startValue, int destValue) {
        string temp="";
        dfs(root,startValue,temp);
        string sp=ans;
        temp="";
        flag=0;
        dfs(root,destValue,temp);
        string dp=ans;
       // cout<<sp<<endl<<dp<<endl;
        int common=0;
        for(;common<sp.length()&&common<dp.length()&&sp[common]==dp[common];common++) ;

        // common被移到第一个不相同的点上
        string res;
        for(int i=common;i<sp.length();i++)
        res+="U";

        res+=dp.substr(common);

        return res;
    }
};

4.

https://leetcode-cn.
com/problems/valid-arrangement-of-pairs/

1. 构图
2. dfs: 先深搜下一个点,在push当前路径
3. 每dfs一次,出发点就要pop_back一次,目的是删掉该边,使得每条边只遍历一次(也可以用map记录边)
4.将ans 反转,具体为啥这样就可以,我也不清楚

class Solution {
public:
unordered_map<int, vector<int> >G;
map<int,int> in,out;
vector<vector<int> > ans;
    void dfs(int x){
        auto &v=G[x];
        while(v.size()){
            int a=v.back();
            v.pop_back();
            dfs(a);            
            ans.push_back(vector<int>{x,a});
        }
}

    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        for(auto it:pairs)
        {
        G[it[0]].push_back(it[1]);
        in[it[1]]++;
        out[it[0]]++;
        }
            
        for(auto &it:pairs){
            if(out[it[0]]>in[it[0]]){
                dfs(it[0]);
                break;
            }
        }
        if(!ans.size()) {
                dfs(pairs[0][0]);
        }
        reverse(ans.begin(),ans.end());
        return ans;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值