自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(49)
  • 收藏
  • 关注

原创 LeetCode -654. 最大二叉树

题目给定一个不含重复元素的整数数组 nums 。一个以此数组直接递归构建的 最大二叉树 定义如下:二叉树的根是数组 nums 中的最大元素。左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。返回有给定数组 nums 构建的 最大二叉树 。思路找到数组最大值的索引 maxIndex,以此位置上的值构造节点即为当前数组的根节点。递归(left,maxIndex),和(maxIndex + 1,right)。复杂度分析假设树

2021-01-13 21:11:26 213

原创 Spring Boot 的自动配置是如何实现的?

Spring Boot 自动配置的原理SpringBoot 使用起来非常方便,核心就在于自动配置,接下来分析一下SpringBoot自动配置的实现原理。(2.4.1)@SpringBootApplication这是 SpringBoot 主类上的注解,来看一下它的源码:@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@Ena

2021-01-13 17:22:35 260

原创 LeetCode - 653. 两数之和 IV - 输入 BST

题目给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。思路创建一个 set,DFS遍历二叉树的,检查 set 中是否包含 target - node.val,如果包含,返回 true,如果不包含,则将 node.val 加入 set 中。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/** * Definition for a binary tree

2021-01-12 20:37:56 169

原创 LeetCode - 637. 二叉树的层平均值

题目给定一个二叉树,计算 整个树 的坡度 。一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。整个树 的坡度就是其所有节点的坡度之和。思路定义一个求二叉树节点和的方法(dfs)。定义一个求二叉树节点坡度的方法。定义一个遍历二叉树,对各节点坡度求和的方法(dfs)。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度

2021-01-11 20:43:16 115

原创 LeetCode - 563. 二叉树的坡度

题目给定一个二叉树,计算 整个树 的坡度 。一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。整个树 的坡度就是其所有节点的坡度之和。思路定义一个求二叉树节点和的方法(dfs)。定义一个求二叉树节点坡度的方法。定义一个遍历二叉树,对各节点坡度求和的方法(dfs)。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度

2021-01-04 20:58:35 99

原创 LeetCode - 559. N 叉树的最大深度

题目给定一个 N 叉树,找到其最大深度。思路递归求最大深度。。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/*// Definition for a Node.class Node { public int val; public List<Node> children; public Node() {} public Node(int _val) {

2020-12-28 20:57:00 56

原创 LeetCode - 543. 二叉树的直径

题目给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。思路经过某个节点的路径长度中的最大值,就是它的左子树的高度 + 右子树的高度。遍历所有的节点,取最大值,就是这个树的直径长度。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/** * Definition for a binary tree node. * public cl

2020-12-22 21:13:01 110

原创 LeetCode - 530. 二叉搜索树的最小绝对差

题目给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。思路绝对值的最小值,那就是最接近的两个点,也就是根节点和左子树的最右侧节点或者根节点和右子树的最左侧节点。定义两个函数:maxLeft() minRight(),然后 dfs 递归计算。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/** * Definition for a binary tree node. * pu

2020-12-21 20:31:14 84

原创 LeetCode - 515. 在每个树行中找最大值

题目您需要在二叉树的每一行中找到最大的值。思路BFS 同时记录下当前行的最大的值。关键:定义两个变量,用于判断各节点是否处于同一行。thisLevelNums = 当前行节点数nextLevelNums = 下一行节点数入栈一个节点,nextLevelNums ++;出栈一个节点,thisLevelNums --;直到 nextLevelNums == 0 时,到达行尾,将最大值加入 List。thisLevelNums 下移一层:thisLevelNums = nextLevelN

2020-12-15 21:32:16 80

原创 LeetCode - 513. 找树左下角的值

题目给定一个二叉树,在树的最后一行找到最左边的值。思路BFS 同时记录下当前行的最左边的值,最终返回它。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; *

2020-12-14 20:47:32 68

原创 LeetCode - 404. 左叶子之和

题目设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。思路DFS 前序遍历组成 String,反序列化时再按相同顺序生成二叉树。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/** * Definition for a binary tree node. * public class

2020-12-07 20:57:42 76

原创 LeetCode - 257. 二叉树的所有路径

题目给定一个二叉树,返回所有从根节点到叶子节点的路径。思路DFS 搜索,参数除了子节点外,再传入当前节点的路径和结果 List复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode

2020-12-04 16:35:59 66

转载 LeetCode - 236. 二叉树的最近公共祖先

题目给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。思路与 Q235 的区别在于本题为二叉树而非二叉搜索树。我们可以用哈希表存储所有节点的父节点,然后我们就可以利用节点的父节点信息从 p 结点开始不断往上跳,并记录已经访问过的节点,再从 q 节点开始不断往上跳,如果碰到已经访问过的节点,那么这个节点就是我们要找的最近公共祖先。复杂度分析假设树有 n 个节点。时间复杂度O(2n),遍历整棵树两次。空间复杂度O(3n),空间复杂度与整棵树的节点数相关,递归+两个List。代码/*

2020-12-03 17:23:44 61

原创 LeetCode - 235. 二叉搜索树的最近公共祖先

题目给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。说明:所有节点的值都是唯一的。p、q 为不同节点且均存在于给定的二叉搜索树中。二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;思路递归:两个节点在当前节点不同侧,返回当前节点。当前节点的值等于其中一个节点,返回当

2020-11-26 17:47:29 74

原创 LeetCode - 222. 完全二叉树的节点个数

题目给出一个完全二叉树,求出该树的节点个数。思路Emm… 直接深度优先遍历吧复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度与整棵树的节点数相关。代码class Solution { public static int countNodes(TreeNode root) { if (root == null) { return 0; } int left = c

2020-11-26 17:06:12 66

原创 LeetCode - 199. 二叉树的右视图

题目给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。思路右视图就是每层的最右侧节点。广度优先遍历,每层最后一个节点加入到列表中。具体实现方法:在广度优先的基础上,维护两个指针:numsOfThisLevel: 代表 Queue 中本层的节点数,numsOfNextLevel:代表 Queue 中下一层的节点数。每当从队列中取出一个节点 node 时,numsOfThisLevel 减 1,每当将 node 的左节点或者右节点加入队列是,numsO

2020-11-24 17:56:01 120

原创 LeetCode - 129. 求根到叶子节点数字之和

题目给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。例如,从根到叶子节点路径 1->2->3 代表数字 123。计算从根到叶子节点生成的所有数字之和。说明: 叶子节点是指没有子节点的节点。思路将传递来的值(初始为0)乘以十,再加上根节点的值的和,分别传递给左右两个子树。左、右两个子树拿到父节点的值后乘以十,再加上根节点的值然后传递给它们的子树。直到叶子节点,再把和都相加,即为结果。复杂度分析假设树有 n 个节点。时间复杂

2020-11-11 21:31:52 120

原创 一篇文章学会 Gradle !

Gradle构建工具的作用依赖管理测试、打包、发布与 Maven 的区别Gradle 在 Maven 的基础上使用 Groovy 来管理构建脚本,而不是 XML。简洁。配置 POM 太繁琐灵活。Groovy,可以使用 task。Groovy 语法必须要懂这些最基本的:可选的类型定义def version = 1assertassert version == 2括号是可选的println version字符串def s1 =‘imooc’ 仅仅是字符

2020-11-11 11:38:11 326

原创 LeetCode - 114. 二叉树展开为链表

题目给定一个二叉树,原地将它展开为一个单链表。思路找到左子树的最右边节点将右子树接到左子树的最右边节点将左子树插入到原先右子树的位置考虑新的右子树的节点,一直重复上边的过程,直到新的右子树为 null复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(1),空间复杂度为常数。代码class Solution { public void flatten(TreeNode root) { while (root != null){

2020-11-09 16:51:28 79

原创 LeetCode - 113. 路径总和 II

题目给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。说明: 叶子节点是指没有子节点的节点。思路我们可以采用深度优先搜索的方式,枚举每一条从根节点到叶子节点的路径。当我们遍历到叶子节点,且此时路径和恰为目标和时,我们就找到了一条满足条件的路径。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n),空间复杂度取决二叉树的节点数。代码class Solution { List<List<Integer&

2020-11-05 22:04:46 110

原创 LeetCode - 112. 路径总和

题目给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。说明: 叶子节点是指没有子节点的节点。思路核心思想:将路径上的所有节点的值相加的和一路向下传递,直到叶节点,再检查所有叶子节点,有目标值的话,就返回 true。递归。定义一个方法 hasPathSum(TreeNode root, int sum, int pathSum):将传来的路径上的节点总和与当前节点值相加,得出路径和。当根节点左、右子树均为 null 时,此节点为叶子节点

2020-11-04 21:15:59 53

原创 LeetCode - 111. 二叉树的最小深度

思路给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。定一个辅助方法,求二叉树的高度。递归:如果根节点为 null,返回 0.如果根节点不为 null,返回左、右子树二者中最高的高度 + 1。直接递归检查每个节点的左右两个子树的高度差是否小于等于 1。复杂度分析假设树有 n 个节点。时间复杂度O(n2),遍历两遍整棵树(检查高度差遍历一遍,同时计算深度遍历一遍)。空间复杂度O(nn2),空间复杂度取决二叉树的节点数。代码class

2020-11-03 17:04:43 134

原创 LeetCode - 110. 平衡二叉树

思路一棵高度平衡二叉树定义为:一个二叉树 每个节点 的左右两个子树的高度差的绝对值不超过 1 。定一个辅助方法,求二叉树的高度。递归:如果根节点为 null,返回 0.如果根节点不为 null,返回左、右子树二者中最高的高度 + 1。直接递归检查每个节点的左右两个子树的高度差是否小于等于 1。复杂度分析假设树有 n 个节点。时间复杂度O(n2),遍历两遍整棵树(检查高度差遍历一遍,同时计算深度遍历一遍)。空间复杂度O(nn2),空间复杂度取决二叉树的节点数。代码cla

2020-11-02 22:22:05 41

原创 LeetCode - 108. 将有序数组转换为二叉搜索树

思路两个要点:二叉搜索树。每个节点的左右两个子树的高度差都不超过 1 。因为给定数组是有序的,那我们很容易就能找到适合做 root 的值,即数组最中间的那个值。这样把数组分成了左、右两部分,root 的左节点就是左边数组中最中间的那个值,root的右节点就是右边数组中最中间的那个值。递归,直到数组长度为 0 时,返回 null。数组长度为 1 时,返回唯一值构成的节点。最后返回 root。复杂度分析假设树有 n 个节点。时间复杂度O(n),遍历整棵树。空间复杂度O(n

2020-10-22 21:11:29 56

原创 LeetCode - 107. 二叉树的层次遍历 II

思路广度优先遍历的变形。维护一个 Queue,首先将根节点加入到 Queue 中。维护两个计数器,numsOfThisLevel:记录本层的节点数, numsOfSonLevel:记录下一层的节点数。维护一个外层 List<List>,和一个 内层的 List。循环,当 Queue 不为空时:取出一个节点,把它的 val 加入内层List。当它的左节点不为空时,将它的左节点加入到队列中。并且下层的节点数 + 1;当它的右节点不为空时,将它的右节点加入到队列中。并且下层的节点数

2020-10-22 20:12:23 67

原创 LeetCode - 103. binary-tree-zigzag-level-order-traversal

思路广度优先遍历。维护一个 Queue,首先将根节点加入到 Queue 中。维护两个计数器,numsOfThisLevel:记录本层的节点数, numsOfSonLevel:记录下一层的节点数。维护一个标志位 needReverse,初始置为false。维护一个外层 List<List>,和一个 内层的 List。循环,当 Queue 不为空时:取出一个节点,把它的 val 加入内层List。当它的左节点不为空时,将它的左节点加入到队列中。并且下层的节点数 + 1;当它的右节

2020-10-15 20:49:01 49

原创 LeetCode - 102. binary-tree-level-order-traversal

思路广度优先遍历。维护一个 Queue,首先将根节点加入到 Queue 中。维护两个计数器,numsOfThisLevel:记录本层的节点数, numsOfSonLevel:记录下一层的节点数。维护一个外层 List<List>,和一个 内层的 List。循环,当 Queue 不为空时:取出一个节点,把它的 val 加入内层List。当它的左节点不为空时,将它的左节点加入到队列中。并且下层的节点数 + 1;当它的右节点不为空时,将它的右节点加入到队列中。并且下层的节点数 + 1

2020-10-14 21:44:45 58

原创 LeetCode - 101. SymmetricTree

思路想要判断一棵二叉树是否是镜像对称的,只要它的左子树和右子树是镜像对称的即可。想要判断两棵树(A、B)是否是镜像对称的,那么需要在同时遍历这两棵树的时候,一棵树(A)的指针向左走,一棵树(B)的指针向右走。当两棵树的根节点都为 null 时,这两棵树镜像对称。(emm。。。null 与 null 对称)当两棵树的根节点有一个为 null,另一个不为 null 时,这两棵树不对称。当两棵树的根节点都不为空并且根节点的值相等时,如果A的左子树与B的右子树对称,B的左子树与A的右子树对称,那么两棵树是

2020-10-13 21:17:54 74

原创 LeetCode - 100. same tree

思路深度优先搜索。复杂度分析时间复杂度O(min(m,n)),m、n分别为两个二叉树的节点数。当m、n相等时,最多查找完所有节点,确定两棵树相同。当m、n不相等时,最多查找完含有较少的节点数的那棵树。空间复杂度O(min(m,n)),其中 m 和 n 分别是两个二叉树的节点数。空间复杂度取决于递归调用的层数,递归调用的层数不会超过较小二叉树的高度,最坏的情况下,二叉树的高度等于节点数。代码public static boolean isSameTree(TreeNode p, Tr

2020-10-12 20:51:58 56

原创 LeetCode - 95.unique-binary-search-trees-ii

思路遍历 1 到 n,列出所有以 i 为根节点的二叉搜索树。因为BST的特性,如果 i 为根节点,那么左子树由 [1, i - 1] 组成,右子树由 [i + 1, n] 组成。[start, end] 模式。当一个节点的start > end,说明这个节点是null。当 start == end 时,说明只有一个数字,只有一个节点。遍历 start 到 end。获得左子树的所有组合,获得右子树的所有组合,以 i 为 root,两两组合左右子树节点。代码public class U

2020-09-28 21:32:45 72

原创 LeetCode - 98. validate-binary-search-tree

思路递归二叉树:检查当前节点:如果当前节点为null,返回false。如果左节点不为空,检查左节点的值是否小于根节点。如果不小于根节点,返回false;如果右节点不为空,检查右节点的值是否小于根节点。如果不大于根节点,返回false;当前节点检查通过后,分别检查左子树和右子树。如果左右子树都是true,那么整棵树就是合格的。代码...

2020-09-27 21:58:38 88

原创 LeetCode - 94. binary-tree-inorder-traversal

思路D、L、R 代表三个节点。前序遍历:DLR,根在前中序遍历:LDR,根在中后续遍历:LRD,根在后这题写的很清楚,是中序遍历,所以也不用多讲。代码第一版,只完成了递归,计划二刷改迭代。public class BinaryTreeInorderTraversal94 { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> integers = new A

2020-09-24 21:28:12 55

原创 LeetCode - 15. 3Num

思路一开始上来用了暴力法三重循环,发现难点在于去重。排序后再尝试,发现可以使用双指针法优化。优化后的算法如下:nums 为 null 或者长度小于3 返回空列表排序遍历排序后数组:如果nums[i] > 0,那么没有sum为0的可能,直接返回。左指针 left = i+1;右指针 right = length - 1;当 left < right 时,执行循环:* 如果sum == 0:将三个数添加进列表。并做以下循环,left和right移动到下一个不同的值(去重)。

2020-09-23 21:58:41 60

原创 从零实现一个RPC框架(七)- CompletableFuture

CompletableFuture在rpc框架中用到了 CompletableFuture,所以这篇文章主要讲一下 CompletableFuture。FutureCompletableFuture 是1.8引入的。public class CompletableFuture<T> implements Future<T>, CompletionStage<T>Completable 实现了 Future 接口和 CompletionStage接口。Futu

2020-09-23 17:55:47 333

原创 从零实现一个RPC框架(六)- Netty客户端Handler

Netty客户端Handler在 Netty 配置客户端端时,添加的真正处理业务逻辑的 NettyClientHandler 。概述NettyClientHandler 继承 ChannelInboundHandlerAdapter,覆写 channelRead、userEventTriggered、exceptionCaught三个方法。channelRead :处理服务端返回的数据,交由 CompletableFuture返回(下一篇会讲到 CompletableFuture)给代理方法。us

2020-09-23 16:50:25 774

原创 从零实现一个RPC框架(五)- 客户端代理调用

客户端代理调用因为服务在远程,所以想要让客户端像调用本地服务一样地调用远程服务,需要使用动态代理。关于动态代理,可以看我的另一篇文章:Java动态代理 这里不再赘述。代码实现 RpcClientProxy rpcClientProxy = new RpcClientProxy(rpcClient, rpcServiceProperties); // 拿到了 HelloService 接口的代理对象 HelloService helloService = rpcClientPro

2020-09-23 16:47:24 207

转载 Java反射(五) - 动态代理

# 动态代理可以在运行期动态创建某个 interface 的实例。首先我们先来看看我们平时如何静态的创建实例:定义接口:public interface Hello { void morning(String name);}编写实现类:public class HelloWorld implements Hello { public void morning(String name) { System.out.println("Good morning, "

2020-09-23 16:24:23 267

转载 Java反射(五) - 获取继承关系

获取继承关系获取父类的Class有了 Class 实例,我们还可以获取它的父类的 Class:public class Main { public static void main(String[] args) throws Exception { Class i = Integer.class; Class n = i.getSuperclass(); System.out.Println(n); Class o = n.getSup

2020-09-23 14:35:20 908

转载 Java反射(四) - 调用构造方法

调用构造方法我们通常使用 new 操作符创建新的实例:Person p = new Person();如果通过反射来创建新的实例,可以调用 Class 提供的 newInstance() 方法:Person p = Person.class.newInstance();调用Class.newInstance()的局限是,它只能调用该类的public无参数构造方法。如果构造方法带有参数,或者不是public,就无法直接通过Class.newInstance()来调用。为了调用任意的构造方法,

2020-09-23 14:18:07 481

转载 Java反射(三) - 调用方法

调用方法我们可以通过Class实例获取所有的Method信息。Class类提供了以下几个方法来获取Method:Method getMethod(name, Class...):获取某个public的Method(包括父类)Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)Method[] getMethods():获取所有public的Method(包括父类)Method[] getDeclaredMethods():

2020-09-23 14:05:23 179

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除