随笔分类 - 算法
记录自己不大熟的LeetCode题目
摘要:题目链接 108. 将有序数组转换为二叉搜索树 思路 类似于二分搜索,定位到数组中间 mid,然后左边的子数组构成左子树,右边的子数组构成右子树,mid 处的数字构成根结点。递归构建左右子树即可,最后返回 root。 代码 class Solution { public TreeNode sorte
阅读全文
摘要:题目链接 669. 修剪二叉搜索树 思路 若 root.val 小于边界值 low,则 root 的左子树必然均小于边界值,我们递归处理 root.right 即可; 若 root.val 大于边界值 high,则 root 的右子树必然均大于边界值,我们递归处理 root.left 即可; 若 r
阅读全文
摘要:题目链接 98. 验证二叉搜索树 思路 依据 BST 的定义:左子树的结点都比根结点小,右子树的结点都比根结点大。我们在递归过程中传递根节点的值,判断当前结点值与根结点值的大小关系。 代码 class Solution { public boolean isValidBST(TreeNode roo
阅读全文
摘要:题目链接 230. 二叉搜索树中第K小的元素 思路 利用 BST 中序遍历是有序的特点,同时每遍历完一个结点将 k--,当 k = 0 的时候,当前结点是第 k 个结点 代码 class Solution { private int k; private int result; public int
阅读全文
摘要:题目链接 863. 二叉树中所有距离为 K 的结点 思路 因为在二叉树中,每个结点至多连接三条边,并且其中两条已经通过左右子结点的形式给出,所以我们只需要记录每个结点的父结点即可。 使用 Map 记录每个结点的父结点,再直接以 target 作为源点开始 DFS,记录与 target 距离为 k 的
阅读全文
摘要:题目链接 572. 另一棵树的子树 思路 判断两个树是否相等的三个条件是与的关系,即: 当前两个树的根节点值相等; 并且,s 的左子树和 t 的左子树相等; 并且,s 的右子树和 t 的右子树相等。 而判断 subRoot 是否为 root 的子树的三个条件是或的关系,即: 当前两棵树相等; 或者,
阅读全文
摘要:题目链接 104. 二叉树的最大深度 思路 递归求左右子树的最大深度并取最大值,返回值在最大值上+1。 递归终止条件为 root == null,此时返回 0。 代码 class Solution { public int maxDepth(TreeNode root) { if(root == n
阅读全文
摘要:题目链接 105. 从前序与中序遍历序列构造二叉树 思路 先序遍历的顺序是根左右,中序遍历的顺序是左根右,所以在 preorder 数组中的首元素一定是当前树的树根,再从 inorder 数组中找到这个元素的下标 index,这样 index 的左边是左子树,右边是右子树。之后再分别递归建立左右子树
阅读全文
摘要:题目链接 235. 二叉搜索树的最近公共祖先 思路 与 【DFS】LeetCode 236. 二叉树的最近公共祖先 一模一样 代码 class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, Tre
阅读全文
摘要:题目链接 236. 二叉树的最近公共祖先 思路 代码 class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root == null || root == p
阅读全文
摘要:题目链接 124. 二叉树中的最大路径和 思路 一个子树内部的最大路径和 = 左子树提供的最大路径和 + 根节点值 + 右子树提供的最大路径和。即 dfs(root.left)+root.val+dfs(root.right) 定义dfs函数:返回当前子树能向父节点“提供”的最大路径和。即,一条从父
阅读全文
摘要:题目链接 314. 二叉树的垂直遍历 思路 如图所示,可以对输出列次顺序作如下标记。 将每一列的列号作为 key,同时将该列的所有结点组成的 List 作为 value,使用 HashMap<Integer, ArrayList<Integer>> 进行存储。 注意: 在进行 BFS 的过程中要存储
阅读全文
摘要:题目链接 26. 删除有序数组中的重复项 思路 设定两个指针 i 和 j,使用 j 遍历数组,将与前项不相等的元素放到 i 的位置。 代码 、class Solution { public int removeDuplicates(int[] nums) { int i = 1; int j = 1
阅读全文
摘要:题目链接 283. 移动零 思路 设定两个指针 i 和 j,使用 j 遍历数组,将非零元素送到 i 的位置后 i++。经过第一次循环后所有的非零数都被送到了数字前面,只需要将剩余的位置变为 0 即可。 代码 class Solution { public void moveZeroes(int[]
阅读全文
摘要:题目链接 11. 盛最多水的容器 思路 在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽底边宽度−1: 若向内移动短板,则 可能变大,因此下个水槽的面积可能增大 。 若向内移动长板,则 不变或变小,因此下个水槽的面积一定减小
阅读全文
摘要:题目链接 18. 四数之和 思路 与 【双指针】LeetCode 15. 三数之和 思路相似,但是要注意测试用例可能溢出,需要转换为 long 代码 class Solution { public List<List<Integer>> fourSum(int[] nums, int target)
阅读全文
摘要:题目链接 16. 最接近的三数之和 思路 借鉴 【双指针】LeetCode 15. 三数之和 的思路,只不过把0换成 target 代码 class Solution { public int threeSumClosest(int[] nums, int target) { Arrays.sort
阅读全文
摘要:题目链接 15. 三数之和 思路 可以借鉴 【双指针】LeetCode 167. 两数之和 II - 输入有序数组 的思路,将 nums[i] 作为 target,不断移动 j 和 k 来达到目标。 去重的方法:通过判断 nums[j] == nums[j + 1] 和 nums[k] == num
阅读全文
摘要:题目链接 167. 两数之和 II - 输入有序数组 思路 本思路来自 一张图告诉你 O(n) 的双指针解法的本质原理(C++/Java) 下图是白色部分初始的搜索空间,即 A[0] + A[7] 假如 target > A[0] + A[7],此时 A[7]已经是搜索空间中最大的数了,所以应该让
阅读全文
摘要:题目链接 647. 回文子串 思路 使用中心扩散法解决,在 【双指针】LeetCode 5. 最长回文子串 的代码上稍作修改即可。 代码 class Solution { public int countSubstrings(String s) { int result = 0; for(int i
阅读全文