• 算法模板--LCA求最近公共祖先


    LCA求最近公共祖先

    C++板子

    int d[]=new int[N];
    int f[][]=new int[N][32];
    int n_max=log(N);
    {
        lg[0]=-1;
        for(int i=1;i<=n;i++) lg[i]=lg[i/2]+1;
        dfs(1,0);
        return lca(p1,p2);
    }
    void dfs(int rt,int fn) {
        d[rt]=d[fn]+1;
        f[rt][0]=fn;
        for(int i=1;i<=n_max;i++)
            f[rt][i]=f[f[rt][i-1]][i-1];
    }
    int lca(int x,int y) {
        if(d[x]<d[y]) {int temp=x;x=y;y=temp;}
        for(int i=n_max;i>=0;i--)
            if(d[f[x][i]]>=d[y])x=f[x][i];
        if(x==y) return x;
        for(int i=n_max;i>=0;i--) {
            if(f[x][i]!=f[y][i]) {x=f[x][i];y=f[y][i])};
        }
       	return f[x][0];
    }
    

    java板子

    /**
     leetcode 
     https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
    */
    
    class Solution {
        private Map<Integer,Integer> mp = new HashMap<>();
        private Map<Integer,Integer> mpReverse = new HashMap<>();
        private Map<Integer,TreeNode> mpNode = new HashMap<>();
        private TreeNode root;
        private int n;
        private int lgg[],h[],f[][];
        public void init() {
            List<Integer> tmp = new ArrayList<>();
            concrete(tmp,root);
            logInit();
            dfs(root,0);
        }
    
        public void dfs(TreeNode ft,int fn){
            int rt = mp.get(ft.val);
            h[rt]=h[fn]+1;
            f[rt][0]=fn;
            for(int i=1;i<=lgg[n];i++){
                f[rt][i] = f[f[rt][i-1]][i-1]; 
            }
            if(ft.left != null)
                dfs(ft.left,rt);
            if(ft.right != null)
                dfs(ft.right,rt);
        }
    
        public void logInit() {
            lgg=new int[n+1];
            h=new int[n+1];
            lgg[0]=-1;
    
            for(int i=0;i<=n;i++) 
                lgg[i]=lgg[i/2]+1;
    
            f=new int[n+1][32];
        }
    
        public void concrete(List<Integer> tmp,TreeNode root) {
            concreteDfs(tmp,root);
            Collections.sort(tmp);
            for(int i=0;i<tmp.size();i++){
                mp.put(tmp.get(i),i+1);
                mpReverse.put(i+1,tmp.get(i));
            }
            return ;
        }
    
        public void concreteDfs(List<Integer>tmp,TreeNode root) {
            if(root == null) {
                return ;
            }
            tmp.add(root.val);
            mpNode.put(root.val,root);
            n++;
            concreteDfs(tmp,root.left);
            concreteDfs(tmp,root.right);
        }
    
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            this.root= root;
            init();
            int x = mp.get(p.val);
            int y = mp.get(q.val);
    
            if(h[x]>h[y]) {
                int swap = x;
                x = y;
                y = swap;
            }
            for(int i=lgg[n];i>=0;i--) 
                if(h[f[y][i]]>=h[x]) 
                    y=f[y][i];
            int ret = 0;
    
            if(x==y) {
                ret = x;
            }
            else {
                for(int i=lgg[n];i>=0;i--) 
                    if(f[y][i]!=f[x][i]){
                        y=f[y][i];
                        x=f[x][i];
                    }
                ret = f[x][0];
            }
            ret = mpReverse.get(ret);
            return mpNode.get(ret);
        }
    }
    
  • 相关阅读:
    史上最强大vimrc
    Linux 宿主目录、根目录及/home区别
    ubuntu配置软件源
    Lex入门2
    域名服务器(DNS)工作原理
    SQL Server 2005脚本编辑窗口不能使用Enter,Backspace, Insert等按键
    建立windows2003 域名服务器
    JavaScript操作cookie
    VS2008下设置断点调试JavaScript (IE)
    DNS域名服务器原理与架设(Bind on Linux)
  • 原文地址:https://www.cnblogs.com/backkom-buaa/p/13961765.html
Copyright © 2020-2023  润新知