树常见算法题1

求中序遍历后继节点
class NextNode{
    int value;
    NextNode left;
    NextNode right;
    NextNode parent;

    public NextNode(int value) {
        this.value = value;
    }
}
public class FindNextNode {
	//中序遍历  将节点加到list中
    public static void findAllNextNode(NextNode node, List<NextNode> list){
        if(node == null){
            return;
        }
        if(node.left != null){
            findAllNextNode(node.left,list);
        }

        list.add(node);

        if(node.right != null){
            findAllNextNode(node.right,list);
        }
    }

    public static NextNode findNextNodeTest2(NextNode node){
        //找到头节点
        NextNode par = node;

        while(par.parent != null){
            par = par.parent;
        }


        List<NextNode> list = new ArrayList<>();

        findAllNextNode(par,list);
        System.out.println(list);

        for (int i = 0; i < list.size() - 1; i++) {
            if(list.get(i).equals(node)){
                return list.get(i + 1);
            }
        }


        return null;
    }
}
//递归
public class FindNextNode {
    public static NextNode findLeftNode(NextNode node){
        if(node == null){
            return null;
        }

        if(node.left == null){
            return node;
        }

        return findLeftNode(node.left);
    }

	
    public static NextNode findNextNodeTest(NextNode node){
        if(node.right != null){
            return findLeftNode(node.right);
        }

        NextNode parentNode = node.parent;

        while(parentNode != null && parentNode.right ==node){
            node = parentNode;
            parentNode = node.parent;
        }
        return parentNode;
    }

}
判断平衡二叉树
public class ACLTest {

    //每一次递归传递的信息
    static class MSG{
        int height;
        boolean isAVLTree;

        public MSG() {
        }

        public MSG(int height, boolean isAVLTree) {
            this.height = height;
            this.isAVLTree = isAVLTree;
        }
		
        get()...
        set()...
    }


    public static MSG isAVL(Node head){
        if(head == null){
            return new MSG(0, true);
        }

        MSG msgLeft = isAVL(head.left);
        MSG msgRight = isAVL(head.right);

        MSG msg = new MSG();
		
        //求出树的高度
        msg.height = Math.max(msgLeft.height,msgRight.height) + 1;
        //判断是否是平衡二叉树
        msg.isAVLTree = msgLeft.isAVLTree && msgRight.isAVLTree && (Math.abs(msgLeft.height - msgRight.height) <= 1);

        return msg;
    }


    public static boolean isAVLTest(Node head){
        MSG avl = isAVL(head);
        return avl.isAVLTree;
    }
}
派对的最大快乐值
/***
 * 公司的人员结构可以看作是一颗标准的没有环的多叉树,树的肉头点是唯一的老板,
 * 除老板外每个员工的都有唯一的直接上级。
 * 叶节点是没有任何我下属的基层员工,
 * 除基层员工外,每个员工都有一个或多个直接下级
 */


/***
 * 派对的最大快乐值,你可以决定哪些员工来,哪些员工不来,规则
 *
 * 1.如果某个员工来了,那么这个员工的所有直接下级都不能来,
 * 2.派对的整体快乐值是所有到场员工快乐值的累加
 * 3.你的目标的是让派对的整体的快乐值尽量大
 *
 * 给定一颗多叉树的头节点boss 请返回派对的最大快乐值
 *
 */

class Employee{
    //这个员工的快乐值
    public int happy;
    //下属
    List<Employee> subordinates;

    public Employee(int happy) {
        this.happy = happy;
    }
}

public class MaxHappy{

    //每一次递归返回的信息
    static class Info{
        //头节点来时最大快乐值
        public int withHead;
        //头节点不来是最大快乐值
        public int withOutHead;
    }

    public static Info process(Employee e){
        //如果是基层员工
        //返回一个Info  第一个参数,如果这个员工参加的快乐值,如果这个员工不参加的快乐值为0
        if(e.subordinates == null){
            return new Info(e.happy,0);
        }

        //如果不是基层员工
        //定义两个变量  。如果这个员工参加  或者这个员工不参加

        //如果参加需要先加上这位员工的快乐值
        int withHeadHappy = e.happy;
        int withOutHeadHappy = 0;

        //对这位员工的直接下层进行循环访问
        for(Employee next : e.subordinates){
            //得到下属的信息
            Info nextInfo = process(next);
            //如果这位员工参加,那么它的直接下属不能参加,所以于下属的withOutHead相加
            withHeadHappy += nextInfo.withOutHead;
            ///如果这位员工不参加,那么它的直接下属可以参加,所以于下属的withHead相加
            withOutHeadHappy += Math.max(nextInfo.withHead,nextInfo.withOutHead);
        }
        //返回这个员工参加或不参加有的快乐值
        return new Info(withHeadHappy,withOutHeadHappy);
    }

    public static int  MaxHappyTest(Employee employee){
        Info process = process(employee);
        return process.withOutHead > process.withHead ? process.withOutHead : process.withHead;
    }
}
返回整颗二叉树的最大距离
public class MaxDistance {

    static class Info{
        //最大距离
        public int MaxDistance;
        //树的高度
        public int height;

        public Info(int maxDistance, int hight) {
            MaxDistance = maxDistance;
            this.height = hight;
        }
        
    }


    public static Info process(Node head){
        if(head == null){
            return new Info(0,0);
        }

        Info leftInfo = process(head.left);
        Info rightInfo = process(head.right);

        int height = Math.max(leftInfo.height,rightInfo.height) + 1;

        int maxDistance = Math.max(Math.max(leftInfo.MaxDistance,rightInfo.MaxDistance)
                                ,rightInfo.height + leftInfo.height + 1);

        return new Info(maxDistance,height);
    }

    public static int  MaxDistanceTest(Node head){
        return process(head).MaxDistance;
    }
    
    
}
求两个节点最近的父节点
  • 方法一 HashMap + HashSet
public static void findAll(Node head, Map<Node,Node> map){
    if(head == null){
        return;
    }
    if(head.left != null){
        map.put(head.left,head);
        findAll(head.left,map);
    }

    if(head.right != null){
        map.put(head.right,head);
        findAll(head.right,map);
    }

}

public static Node RecentlyFatherTest(Node head,Node node1,Node node2){
    HashMap<Node, Node> map = new HashMap<>();
    map.put(head,null);
    findAll(head,map);

    HashSet<Node> set = new HashSet<>();
    set.add(node1);
    while(true){
        if (map.get(node1) == null){
            break;
        }
        set.add(map.get(node1));
        node1 = map.get(node1);
    }

    while(true){
        if( set.contains(node2) ){
            break;
        }

        node2 = map.get(node2);
    }
    return node2;
}
  • 方法二 递归
//每一次递归返回的信息
static class Info{
    public Node ans;
    public boolean findNode1;
    public boolean findNode2;

    public Info(Node ans, boolean findNode1, boolean findNode2) {
        this.ans = ans;
        this.findNode1 = findNode1;
        this.findNode2 = findNode2;
    }
}


public static Info RF(Node head,Node node1,Node node2){
    if(head == null){
        return new Info(null,false,false);
    }

    Info leftInfo = RF(head.left,node1,node2);
    Info rightInfo = RF(head.right,node1,node2);


    boolean findNode1 = head == node1 || leftInfo.findNode1 || rightInfo.findNode1;
    boolean findNode2 = head == node2 || leftInfo.findNode2 || rightInfo.findNode2;

    Node ans = null;
    if(leftInfo.ans != null){
        ans = leftInfo.ans;
    }
    if (rightInfo.ans != null){
        ans = rightInfo.ans;
    }
    if(ans == null){
        if(findNode1 && findNode2){
            ans = head;
        }
    }

    return new Info(ans,findNode1,findNode2);
}

public static Node RecentlyFatherTest2(Node head,Node node1,Node node2){
    Info info = RF(head, node1, node2);

    System.out.println(info.ans);
    return info.ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值