leecodecode【面试150】【2026.6.25打卡-java版本】

路径总和

要点:dfs

java 复制代码
/**
 * 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 hasPathSum(TreeNode root, int targetSum) {
        if(root == null){
            return false;
        }

        targetSum -= root.val;

        if(root.left == null && root.right ==null){
            return targetSum == 0;
        }

        return hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum);
        
    }
}

求根节点到叶节点数字之和

要点:dfs,递归

java 复制代码
/**
 * 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 int sumNumbers(TreeNode root) {
        return dfs(root, 0);
    }

    public int dfs(TreeNode root, int preSum){
        if(root == null){
            return 0;
        }

        int sum = preSum*10 + root.val;

        if(root.left == null && root.right == null){
            return sum;
        }else{

            return dfs(root.left, sum) + dfs(root.right,sum);
        }


    }
}

二叉树中的最大路径和

要点:dfs,定义max,记得和0比较

java 复制代码
/**
 * 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 int max=  Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return max;
    }

    public int dfs(TreeNode root){
        if(root == null){
            return 0;
        }

        int left = dfs(root.left);
        int right = dfs(root.right);

        max = Math.max(max, root.val+left+right);

        return Math.max(0,Math.max(left, right)+root.val);
    }
}

二叉树的中序遍历

要点:

java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        inorder(root, res);
        return res;
    }

    public void inorder(TreeNode root, List<Integer> res) {
        if (root == null) {
            return;
        }
        inorder(root.left, res);
        res.add(root.val);
        inorder(root.right, res);
    }
}

完全二叉树的节点个数

要点:dfs

java 复制代码
class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) return 0;

        int leftHeight = getHeight(root.left);
        int rightHeight = getHeight(root.right);

        if (leftHeight == rightHeight) {
            // 左子树是满二叉树,高度为 leftHeight
            // 节点总数 = 左子树(2^leftHeight - 1) + 根节点(1) + 右子树节点数
            return (1 << leftHeight) + countNodes(root.right);
        } else {
            // 右子树是满二叉树,高度为 rightHeight(此时 leftHeight = rightHeight + 1)
            // 节点总数 = 右子树(2^rightHeight - 1) + 根节点(1) + 左子树节点数
            return (1 << rightHeight) + countNodes(root.left);
        }
    }

    // 计算以 node 为根的完全二叉树的高度(沿左子树一直走)
    private int getHeight(TreeNode node) {
        int height = 0;
        while (node != null) {
            height++;
            node = node.left;
        }
        return height;
    }
}

随机知识

四个核心维度对比 CMS 和 G1 收集器,分别是设计目标、内存划分、回收流程、停顿控制:

  1. 设计定位与目标不同 CMS 是老年代专用收集器,核心目标是最小化 STW 停顿 ,专注优化老年代回收,不处理新生代;G1 是一款全堆分代收集器,面向大内存、多核服务器,目标是可预测的停顿时间模型,能自定义最大停顿阈值,新生代、老年代统一由 G1 管理,兼顾低停顿与吞吐量。
  2. 堆内存划分方式完全不同 CMS 沿用传统分代模型:新生代 Eden/S0/S1 + 连续整块老年代,老年代是一整片连续内存;G1 把整个 Java 堆切分成多个大小相等的独立 Region,分 Eden 区、Survivor 区、Old 区、Humongous 大对象区,老年代不再连续,回收时只选择垃圾最多的 Region 清理,也就是 "标记整理 + 局部回收"。
  3. 回收算法与碎片问题差异 CMS 老年代使用标记 - 清除算法,不会整理内存,长期运行会产生大量内存碎片,内存不足时必须触发 Full GC 做压缩整理,STW 时间极长;G1 整体是标记整理,分阶段局部整理,每次只回收部分 Region,回收后自动压缩存活对象,几乎不会产生内存碎片,大幅减少 Full GC 触发概率。
  4. STW 阶段与并发阶段流程区别 CMS 回收分 6 步,其中只有初始标记、重新标记两段短暂 STW,并发标记、并发清除全程用户线程并行;但并发清除阶段会产生浮动垃圾,无法处理本轮新产生的垃圾。 G1 分为年轻代回收 Mixed 混合回收、Full GC,初始标记、重新标记、最终标记 STW,新增并发预估停顿机制,根据设置的停顿上限选择回收 Region 数量;同时 G1 有记忆集 Card Table 跟踪跨 Region 引用,解决扫描全堆开销,CMS 只卡表区分新生代到老年代引用,无跨老年代 Region 跟踪设计。

完整 JVM 运行时数据区(彩色标注分区)

  1. 线程私有区(每个线程独立,线程销毁释放)
    • 程序计数器 PC:记录当前执行字节码行号,无 OOM
    • 虚拟机栈 Java Stack:局部变量、方法栈帧,栈溢出 StackOverflowError
    • 本地方法栈 Native Stack:管理 native 本地方法
  2. 线程共享堆 Heap(最大内存区域)
    • 新生代:Eden 区、Survivor0、Survivor1(复制算法)
    • 老年代 Old:长期存活对象(CMS 标记清除 / G1 标记整理)
    • Humongous 区(G1 独有):超大对象直接分配老年代 Region
  3. 线程共享元空间 Metaspace(替代永久代,堆外直接内存)
    • 存储类元信息、方法、常量、符号引用,本地内存分配
    • 运行时常量池:元空间内部,存放字符串常量、字面量、符号引用
  4. 直接内存 Direct Buffer(堆外本地内存,不属于 JVM 运行时数据区) NIO 缓冲区使用,不受 - Xmx 限制,受系统内存限制,需要手动释放

碎碎念:后续会更新每天学习的八股和算法 题,开始准备秋招的第46天。努力连续更新100天!以后每天就按,秋招项目【java +agent】,科研,必做项目,算法,八股,锻炼身体来总结。

总结:实习干活,真是身体健康最重要,尽量还是多学点,现在老抵触学习了啊啊啊啊啊

1.算法面试150 91/150 2h

2.秋招项目,【java 项目】,

【agent 项目 】,

3.科研要跑一下,,

4.检测项目,6h

6.背八股,

7.锻炼身体,无