【英雄算法六月集训】Day17

【英雄算法六月集训】Day17

1367. 二叉树中的列表

学到了什么

Ⅰ 一直向下的路径中的节点顺序 和链表元素 完全相等的判定方式 -----DFS

Ⅱ 熟悉DFS,已经初步具备了意识,大概知道DFS 递归怎么去写

特征:DFS二叉树

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean check(TreeNode root,ListNode head){
        if(root==null){
            if(head!=null){
                return false;
            }
            return true;
        }
        if(head==null){
            return true;
        }
        if(head.val != root.val){
            return false;
        }
        return check(root.left,head.next) || check(root.right,head.next);
    }
    public boolean dfs(TreeNode root,ListNode head){
        if(check(root,head)){
            return true;
        }
        if(root == null){
            return false;
        }
        return dfs(root.left,head)||dfs(root.right,head);
    }
    public boolean isSubPath(ListNode head, TreeNode root) {
        return dfs(root,head);
    }
}

1361. 验证二叉树

学到了什么

Ⅰ 二叉树的判定规则

Ⅱ 当出现数组类型的记录树节点关系的,记得利用hash数组

Ⅲ 再次熟悉DFS,已经初步具备了意识,大概知道DFS 递归怎么去写

特征:DFS二叉树

class Solution {
    int[] hash = new int[10010];
    public void dfs(int[] leftChild,int[] rightChild,int x){
       hash[x]=1;
       if(leftChild[x]!=-1){
           dfs(leftChild,rightChild,leftChild[x]);
       }
       if(rightChild[x] !=-1){
           dfs(leftChild,rightChild,rightChild[x]);
       }
    }
    public boolean validateBinaryTreeNodes(int n, int[] leftChild, int[] rightChild) {
        int[] deg = new int[10010];

        for(int i=0;i<leftChild.length;++i){
            if(leftChild[i] != -1){
                ++deg[leftChild[i]];
            }

            if(rightChild[i] != -1){
                ++deg[rightChild[i]];
            }
        }
        //统计入度为0的节点
        int cnt = 0;
        int root =-1;
        for(int i=0;i<n;++i){
            if(deg[i]==0){
                ++cnt;
                root=i;
                //入度有2个以上
                if(cnt >1){
                    return false;
                }
            }
            if(deg[i]>1){
                return false;
            }
        }
        //没有一个节点有入度 这不是一个连通图
        if(cnt==0){
            return false;
        }

        //到这里函数还没有返回,说明基本满足树的条件,还需要看有没有单独的节点
        //dfs访问一遍这个树,如果所有节点都被访问,则表示他是一个合格的二叉树
        dfs(leftChild,rightChild,root);
        for(int i=0;i<n;++i){
            if(hash[i]==0){
                return false;
            }
        }
        return true;
    }
}

1457. 二叉树中的伪回文路径

学到了什么

Ⅰ DFS

Ⅱ 二进制存储数据奇数个数

特征:DFS二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int totalCnt=0;
    public boolean isLeaf(TreeNode root){
        return root.left == null && root.right == null;
    }
    public void dfs(TreeNode root,int sum){
        if(root == null){
            return;    
        }
        //只统计奇数个的值,如果一个数是偶数个,那么相应位置上的值就为0
        sum^=1<<(root.val);
        if(isLeaf(root)){
            int c=0;
            //这块意思,比如sum^=1<<(root.val)在做一个奇数统计
            //最低位与1做与运算,如果一个数为奇数,那么最低位,必然是1
            //则表示该位所代表的数是奇数个数(因为值为0-9)
            //,然后右移sum( sum>>=1)相当于统计下一个数 
            while(sum!=0){
                c+=(sum&1);
                sum>>=1;
            }
            if(c<=1){
                ++totalCnt;
            }
            return;
        }
        dfs(root.left,sum);
        dfs(root.right,sum);
    }
    public int pseudoPalindromicPaths (TreeNode root) {
        //设计一些路径遍历,上来二话不说 dfs 架子搭好
        dfs(root,0);
        return totalCnt;
    }
}

1373. 二叉搜索子树的最大键值和

学到了什么

Ⅰ DFS

特征:DFS二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class MValue{
    int maxv;
    int minv;
    int sumv;
    int isByn;
}
class Solution {
    int ret=0;
    public void dfs(TreeNode root,MValue mValue){
        if(root == null){
            mValue.maxv= -1000000000;
            mValue.minv=1000000000;
            mValue.sumv=0;
            mValue.isByn=1;
            return;
        }

        MValue leftMValue = new MValue();
        MValue rightMValue = new MValue();
        dfs(root.left,leftMValue);
        dfs(root.right,rightMValue);

        mValue.sumv = root.val;
        if(leftMValue.maxv < root.val && root.val < rightMValue.minv &&leftMValue.isByn==1&&rightMValue.isByn==1){
            mValue.isByn=1;
            mValue.sumv = root.val+leftMValue.sumv+rightMValue.sumv;
        }else{
            mValue.isByn=0;
            mValue.sumv=0;
        }
        mValue.maxv = Math.max(leftMValue.maxv,rightMValue.maxv);
        mValue.maxv = Math.max(mValue.maxv,root.val);

        mValue.minv = Math.min(leftMValue.minv,rightMValue.minv);
        mValue.minv = Math.min(mValue.minv,root.val);

        ret=Math.max(ret,mValue.sumv);
    }
    public int maxSumBST(TreeNode root) {
        MValue mValue=new MValue();
       dfs(root,mValue);
       return ret;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值