算法与数据结构
文章平均质量分 72
LeetCode 刷题笔记
Bennett 黄柏禧
止于至善
展开
-
二维动态规划状态压缩的一些思考
问题对于以下一段代码:代码来源:labuladongint longestPalindromeSubseq(string s) { int n = s.size(); // dp 数组全部初始化为 0 vector<vector<int>> dp(n, vector<int>(n, 0)); // base case for (int i = 0; i < n; i++) dp[i][i] = 1;原创 2021-10-21 16:04:52 · 253 阅读 · 0 评论 -
Leetcode337 记录
本文是关于一篇文章的解读。三种方法解决树形动态规划问题这篇文章已经描述的很详尽,建议先阅读上面这篇文章。阅读完之后,我想提出以下两个结论:所谓的递归重复调用问题,主要原因出在了:跨层访问节点上。即:爷爷调用孙子节点,而父节点也将调用子节点,那么孙子节点就被调用了两次。从而造成效率降低。但单纯的,父节点只把手伸向它的直接子节点,那么是不会造成效率降低的。递归过程中,递归过程的函数调用的消耗将比直接返回数组大。下面印证一下我的观点:我将作者的思路 3,换成递归的方式来描述:public in原创 2020-11-07 21:29:50 · 114 阅读 · 0 评论 -
Leetcode297:序列化和反序列化
这道题进一步考察了对二叉树的理解。一开始此题没有做出来,最后看答案写了出来。答案来自手画图解』二叉树的序列化与反序列化 | 剖析两种解法答案给了广度遍历和深度遍历两种方案。下面简略的解释一下两种解法。总的来说,两种解法共同考虑的都是,在序列化时保护好 null 值的位置输出,来记录树的结构,以便反序列化恢复。DFS对于深度遍历来说,序列化的过程就是先序遍历的过程。这个无需多言。但是反序列化过程怎么做的呢?由于序列化过程生成了大量的 null 值,导致我在反序列化过程主动放弃了这种解法。其实原创 2020-11-06 21:27:11 · 213 阅读 · 0 评论 -
MapReduce实现矩阵乘法的一些总结
MapReduce实现矩阵乘法的一些总结文章目录MapReduce实现矩阵乘法的一些总结矩阵乘法概述MapReduce 思路具体方法 1具体方法 2具体方法 3实现代码结果分析一些杂杂碎碎Hex 与 bytes 与 Int 的转换Hadoop 环境配置本地调试本地安装 hadoop如何修改 mapper,reducer 数量参考资料矩阵乘法概述对于矩阵乘法 A(i,j)∗B(j,k)=C(i,k)A(i,j) * B(j,k) = C(i,k)A(i,j)∗B(j,k)=C(i,k),有:(i,k原创 2020-11-06 09:53:18 · 2978 阅读 · 0 评论 -
层序遍历总结
以 LeetCode102 作为例子:题目描述思路描述层序遍历需要用到的数据结构是队列。需要考虑的问题是:如何标识当前节点的层数。有以下三种方法:方法 1将每个节点表示为一个二元组 (node, level),这种方法效率太低,不考虑。感兴趣可以参考方法 2遍历完一层节点后,在队列中插入一个标记节点NULL,这个标记节点没有具体意义,只是标识某一层已经遍历结束。这种方法的缺点在于,假如想要在层序遍历过程中,有元素为 NULL,那么标记节点就会出现混淆。这种方法的代码我经常用,如下:c原创 2020-11-04 20:22:28 · 1551 阅读 · 1 评论 -
Leetcode 235. 二叉搜索树的最近公共祖先
题目描述方法 1假如不考虑二叉搜索树这个条件,针对任意树,寻找最近公共祖先:采用动态规划的方法:寻找当前树包含的 key 的数量。(将 p 和 q 视为 key1,key2)若找到 key 数量为 2 的节点,则寻找到结果public class Solution1 { private int key1, key2; TreeNode result; public TreeNode lowestCommonAncestor(TreeNode root, TreeNode原创 2020-10-28 20:26:49 · 98 阅读 · 0 评论 -
记录*:LeetCode 222
这道题我没做出来,十分挫败。看了答案之后,不仅被作者精妙的思路折服,并且还学习到了一些小技巧。这里直接贴上作者原文题目描述错误思路上面是我的错误思路。我的思路是,通过最左边的路径找到树的高度。然后寻求所有高度为 h-1的节点,最后再计算缺失的节点数,即可得到存在的总数。然而,事实时,当我在遍历高度为 h-1 的节点时,我始终找不到一个好的办法,来进行横向扫描,我总不能进行层序遍历吧,虽然可以解出来,但是把整个树遍历一遍,题目的:完全二叉树这一条件就会完全没有用。我甚至尝试用一个栈来维护所有经原创 2020-10-18 23:03:40 · 91 阅读 · 0 评论 -
记录:Leetcode119
题目描述这个例子比较迷惑。用下面这个:那就是用队列整一个层序遍历就完事了。思路 1直接上代码吧。public class Solution { private final List<Integer> result = new ArrayList<>(); public List<Integer> rightSideView(TreeNode root) { if (root == null) return result;原创 2020-10-16 20:23:36 · 90 阅读 · 0 评论 -
记录:Leetcode173
中等题,理所当然,直接解题。题目描述题目本身不难,需要额外考虑的是空间复杂度和时间复杂度的限制。想要实现 next和 hasNext 功能,照理来说只需要造一个数组即可。但问题是,数组的空间复杂的是 O(n)。那么应该怎么办呢?再看一眼条件,会发现,这棵树是二叉搜索树。思路 1对于二叉搜索树,左子树 < 根 < 右子树 是确定的。那么我们可以仅仅存储根节点,那么左右节点大小关系也就出来了。那么我为什么在上图之中把 3 也存进去了呢?因为我原来打算采用递归,那么如何在到达叶子节点之原创 2020-10-15 22:46:39 · 142 阅读 · 0 评论 -
记录:Leetcode124
这是一道 hard 题,但是看到题到了解到思路仅用了 5 分钟,然而最后调试以及修改枝叶错误画了半个小时。总之做出来了,开心。。。题目描述思路分析以下图是我一开始的思路。我的想法是,对于一个简单二叉树,所有情况无非就是:root,(root,left),(root,left,right),(root,right)那么从子树开始,从下至上递归,求得每个简单二叉树能够起到的最大作用传上去。当然,还有两种情况没考虑,那就是单独的(left)和(right)这两种情况是不能够传上去的。(当然不止,原创 2020-10-11 22:03:58 · 96 阅读 · 0 评论 -
记录:LeetCode117
打算法好快乐啊,写数学作业好烦啊。。。今天的题目是 116 的进阶版,树不再是结构完美的树。题目描述由于树不再是规则的树,因此不能考虑 116 的直接劈砍的方式。因为会出现以下情况:此时采用之前的方式,4-6 这条线无法连接。假如不考虑常量级空间,那么最直观的方法就是进行层序遍历,借助队列。解法 1public class Solution2 { public Node connect(Node root) { if (root == null) return n原创 2020-10-10 23:13:15 · 152 阅读 · 0 评论 -
记录:Leetcode116
文章目录题目描述思路 1思路 2经过这道题,我明白了一个道理:在具备基础知识的条件下,做不出来题往往是被自己的惯性思维局限住了。题目描述看到这里,我一开始蒙了。本来按层序遍历,直接拿个队列广度搜索就能够解决这道题,然而要求常量级空间,这意味着我几乎无法使用任何数据结构进行辅助。那还层序遍历个鬼?然后我又看到了,使用递归解题符合要求?递归解题?那就是要我遍历这个树吧?广度搜索不行,那就深度搜索吧。先序中序后序挑哪个呢?于是我进坑了,下面思路 1 就是我进坑的情况:思路 1写的很杂乱,可原创 2020-10-02 00:24:09 · 94 阅读 · 0 评论 -
记录:LeetCode114
这道题,一开始毫无思路,甚至走错思路,然后经过自己画图,一点一点做出来。一次就 ac,爽到起飞。原来思路对了是这么样的感觉。这次不像往常,先贴一下结果。好了,开心完了,进入正题。题目描述看了题目,接下来复现一下心路历程。心路历程 1这个单链表,仔细一看顺序,是一个先序遍历。那我要做的就是,按先序遍历的顺序去遍历树,然后,当遍历到右节点时,将右节点接到左节点的尾巴上。(细心的人可能已经发现了,我的思路完全没考虑左右:但是当时的我没意识到这个问题,一心想的是,如何在递归过程中知道,我已经可以进原创 2020-09-29 22:29:56 · 164 阅读 · 0 评论 -
记录:LeetCode113
今天心情不佳,随便写写吧。题目描述思路 1和上次一样,照常递归即可。然后就会涉及一个问题:在递归过程中需要维护一个 list 变量。直接上代码:public class Solution1 { private List<List<Integer>> result = new ArrayList<>(); public List<List<Integer>> pathSum(TreeNode root, int sum)原创 2020-09-28 21:57:59 · 100 阅读 · 0 评论 -
Leetcode112:路径总和
题目描述思路 1public class Solution { private int sum; private boolean res = false; public boolean hasPathSum(TreeNode root, int sum) { this.sum = sum; helper(root, 0); return res; } public void helper(TreeNode roo原创 2020-09-23 23:31:03 · 111 阅读 · 0 评论 -
Leetcode 111:二叉树的最小深度
题目描述思路 1递归写法,没什么好说的,一遍过。直接上代码:public class Solution1 { private int min = Integer.MAX_VALUE; public int minDepth(TreeNode root) { if (root == null) return 0; helper(root, 0); return min; } public void helper(Tr原创 2020-09-22 20:52:36 · 100 阅读 · 0 评论 -
Leetcode 110:平衡二叉树
题目描述解释今天上了一天的课,晚上还开会,感觉好累,直接手打完没测试就过了,也不想看答案有没有其他写法。也就是通过递归来判断两个事情:左子树和右子树是否是平衡二叉树左子树和右子树的高度是多少上代码:public class solution1 { public boolean isBalanced(TreeNode root) { int helper = helper(root); return helper != -1; }原创 2020-09-21 22:20:15 · 102 阅读 · 0 评论 -
Leetcode 108:将有序数组转换为平衡 BST
题目描述思路 1这道题没什么好说的,其实树的专题做到现在,关于递归应该也有熟悉了。而在前面的题目中学到的一些知识点,包括:通过使用下标来缩小递归中子问题的范围巧用插入标记值熟练使用队列和栈也会在后面的题目中经常用到。这道题使用下标标识子问题即可。直接代码:public class _108 { private int[] nums; public TreeNode sortedArrayToBST(int[] nums) { this.nums =原创 2020-09-20 20:38:30 · 113 阅读 · 0 评论 -
Leetcode 106:从中序后序构建树
题目描述思路 1这第一种思路,我是借鉴了 105 的循环解法,对中序后序的序列进行分析,来寻求解答。如图,当前序和中序同一位置的元素相同时,表示这些点均为左节点,入栈。当遇到第一个不同的节点时,inorder 所在位置表示为某一子树的根节点到达。通过一个 father 变量标识右节点的链接。代码如下:public class Solution1 { public TreeNode buildTree(int[] inorder, int[] postorder) {原创 2020-09-18 22:33:56 · 114 阅读 · 0 评论 -
Leetcode105:根据前序中序构建树
题目描述思路 1我的思路主要是递归,通过不断缩小问题的规模来解决。递归的参数还是 preorder 和 inorder 两个数组,为了操作简便,preorder 保持不变,inorder 随递归加深不断缩减。边界条件:假设 inorder 只有一个元素,直接返回节点假如 inorder 为空,返回 null代码如下: public TreeNode buildTree(int[] preorder, int[] inorder) { List<Integer&原创 2020-09-15 22:21:12 · 112 阅读 · 0 评论 -
Leetcode107:二叉树的层次遍历 II
题目描述简单题,没什么好说的,按层次遍历,然后每层结果插入 result 结果集头部即可。代码: public List<List<Integer>> levelOrderBottom(TreeNode root) { List<List<Integer>> result = new ArrayList<>(); if (root == null) return result; Que原创 2020-09-14 22:31:28 · 81 阅读 · 0 评论 -
Leetcode103:二叉树的锯齿形层次遍历
题目描述此题算是 102 的一个拓展版。如何层序遍历已在 102 文章讲过,这里主要讲如何在输出时采用 zigzag 输出。思路一将每一层遍历后的结果视情况进行翻转。代码如下:public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> result = new ArrayList<>(); if (roo原创 2020-09-13 21:54:04 · 107 阅读 · 0 评论 -
Leetcode102:二叉树层序遍历(心路历程)
题目描述思路 1使用一个容器来存储每一层的节点。然后撤出所有节点后再加入它们的所有子节点。本来觉得应该建立两个容器,一个容器装当前层,另一个容器一次装入它们的孩子。但是这种做法处理起来很麻烦,浪费空间。问题的关键是:如何将当前层与子层分开,因此我只需要在当前层和子层中间插入任意一个特殊节点标记为当前层结束即可。这里,我将这个特殊的标记节点设为 null代码如下:class Solution { public List<List<Integer>> level原创 2020-09-12 20:59:17 · 167 阅读 · 0 评论 -
Leetcode 101:对称二叉树(心路历程)
题目描述思路分析这个题拿到手上,第一个思考的就是:如何正确的去解读“镜像对称”。第一个想法就是:既然每个形态不同的树,中序遍历结果不同,那么直接对树进行中序遍历,然后比较数组是否对称即可。如上述问题描述中,第一个例子的中序遍历为:【3,2,4,1,4,2,3】,显然以中点对称。第二个例子的中序遍历为:【2,3,1,2,3】,那么无法满足要求。正当我兴高采烈地秒完中序遍历直接提交时,出错了。。。当面对这个树时,中序遍历结果是对称的。思路二究其原因,是由于中序遍历结果把 null 忽略掉没有原创 2020-09-11 20:57:49 · 96 阅读 · 0 评论 -
全面解析DFS(必看)
文章目录引用修改与解释普通的遍历方法前序中序引用在 LeetCode 94的一篇文章看到了进行树的深度遍历的方法。效果是:无论是前序中序后序都是一样的写法。这种方法被作者称为“颜色标记法”。作者为:hzhu212,原文地址这里直接附上原作者的思路分析:其核心思想如下:使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。如果遇到的节点为灰色,则将节点的值输出。class Solution:原创 2020-09-02 16:07:09 · 1085 阅读 · 0 评论 -
Leetcode 100: 相同的树
文章目录题目描述思路题目描述思路与 98 题相同,直接采用树的中序遍历,然后进行比较即可。当然,采用前序或者后序都可以。这里直接贴上代码:class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) { return true; } else if (p == null &&am原创 2020-09-02 15:56:43 · 88 阅读 · 0 评论 -
Leetcode 98: 验证二叉树
文章目录题目描述想法 1想法 2想法 3题目描述想法 1采用递归的方式,判断左节点小于根,右节点大于根。结果:错误。错误案例为:原因:右孩子的左孩子(右孙子)可能小于父亲。 6 < 10,出错。想到的解决方案:在递归过程中吧祖先记录下来,用以后续的比较。想法 2在递归过程中加入祖先,并且加入 bool 标识指示是左孩子还是右孩子。public class Solution1 { public boolean isValidBST(TreeNode root) {原创 2020-09-01 13:20:18 · 214 阅读 · 0 评论 -
Leetcode 17
题目描述题目解析这道题目只需要简单的数字映射到字母即可。组合通过递归即可实现代码class Solution {private: vector&lt;string&gt; res; //存储最终的返回结果 const string letterMap[10]{ "", //0 " ", //1 &q原创 2018-10-28 19:54:54 · 120 阅读 · 0 评论 -
Leetcode 4: Median of Two Sorted Arrays
题目描述解法这道题目假如采取最普通的做法,即为将两个数组结合在一起,再进行排序,然后取出直接取出中位数即可。排序的算法最优复杂度为 O(nlogn),而取出中位数的复杂度为O(n),遍历两个数组的复杂度也是O(n),所以整个算法的复杂度为O(nlogn),明显超过题目的要求,不可采取不过最后在accepted列表里发现有人采取这种方法然后LeetCode给过的。这里附上这种方法的代码c...原创 2018-09-30 17:36:28 · 136 阅读 · 0 评论 -
Leetcode 6: zigzag
题目描述题目分析这道题目要求字符串以曲折形式输出,因此可以根据要显示的曲折字符串的行数n来确定有n个容器,接着遍历字符串将对应位置的字母放在对应的容器里。以行数为4为例,从左到右遍历每个字母依次放在1,2,3,4,3,2,1,。。。。号桶。代码也以这种思想编写即可#include &lt;iostream&gt;using namespace std;class Solution {...原创 2018-10-14 16:22:42 · 149 阅读 · 0 评论 -
Leetcode 11: Container With Most Water
题目链接题目描述解答步骤这一题刚拿到手,首先想到的是使用两层循环,第一层从左到右遍历作为左柱子,第二层从右往左遍历作为右柱子,记录下最大的容水量并输出即可。这种方法的复杂度将大于O(n^2),不采用(以下描述中左右柱子指代选定container的左右边界,数组下标从0开始)接着发现可以添加一些限制条件来减少循环的次数。首先,在左柱子选定(依次从左到右遍历)的情况下,假若左柱子的高...原创 2018-10-05 22:12:37 · 137 阅读 · 0 评论 -
Leetcode 23: Merge k Sorted Lists
题目描述解题思路这道题可以使用归并排序的思想进行操作,不同的是归并排序通过递归,在并的过程中采用的是两个list进行比较。题目要求的是对k个排列好的lists进行操作,因此思路就是每次比较队列头的元素,找出其中最小的,并将该元素写入新的lists内,并将它从所在的队列中pop出来。假如队列达到了末尾,则不进行比较。当所有队列都到达末尾时,停止比较。这道题采用的是lists,因此pop就通过...原创 2018-09-24 12:04:38 · 198 阅读 · 0 评论 -
Leetcode 22: Generate Parentheses
题目描述解题思路拿到这道题,首先思考的是哪些情况下括号匹配会出现错误。题目只列出了正确的括号匹配情况,因此需要自己观察不匹配的情况。首先可以注意到的是,左括号永远是作为开头出现,而右括号永远是作为末尾出现。除了两端之外,右括号的出现必须要求前面已经有左括号。因此一开始的想法是构建一个栈来存储左括号,当往字符串中写入一个左括号时,向栈中push一个左括号,当栈中括号pop出来时,...原创 2018-09-15 20:05:44 · 132 阅读 · 0 评论 -
Leetcode 12: Integer to Roman
题目描述题目分析首先熟悉转换规则,然后可以使用两个list存储对应的映射关系,然后每次从大到小看num是否大于1000,大于900,大于500,若在某个区间的话,就将罗马数字加进来,num减去相应的数值,直到num为0代码展示class Solution(object): def intToRoman(self, num): intForm = [1000,900...原创 2018-10-21 15:34:30 · 135 阅读 · 0 评论 -
Leetcode 64
题目描述这是一道简单的动态规划问题。找最短的和,相当于动态规划求最短路径。因此采用递归很容易实现。#include &amp;lt;iostream&amp;gt;#include &amp;lt;climits&amp;gt;#include &amp;lt;vector&amp;gt;using namespace std;typedef pair&amp;lt;int, in原创 2018-11-04 21:22:05 · 101 阅读 · 0 评论 -
Leetcode 18: 4Sum
题目描述解答LeetCode中关于数字之和还有其他几道,分别是Two Sum 两数之和,3Sum 三数之和,3Sum Closest 最近三数之和,虽然难度在递增,但是整体的套路都是一样的,在这里为了避免重复项,我们使用了STL中的set,其特点是不能有重复,如果新加入的数在set中原本就存在的话,插入操作就会失败,这样能很好的避免的重复项的存在。此题的O(n^3)解法的思路跟3Sum 三数...原创 2018-11-11 23:19:57 · 101 阅读 · 0 评论 -
寻找二叉搜索树的数量
寻找二叉搜索树的数量二叉搜索树设:则有:而:以i为根结点,左边有i-1个节点可以作为左子树,右边有 n - i个节点可以当右子树所以说,由于只关心数量,所以不用考虑原创 2018-11-17 15:08:04 · 1060 阅读 · 0 评论 -
Leetcode 95
问题描述问题分析这个问题是上一篇博客的后继,构造二叉树的过程采用递归即可首先是节点的结构# Definition for a binary tree node.class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None...原创 2018-11-18 15:59:00 · 644 阅读 · 0 评论 -
Single Source Capacity Facility Location Problem
本篇博客涉及贪心算法以及模拟退火算法解决单源设施选址问题问题描述Suppose there are n facilities and m customers. We wish to choose:(1) which of the n facilities to open(2) the assignment of customers to facilitiesThe objective...原创 2018-12-16 12:31:20 · 434 阅读 · 0 评论 -
Leetcode 76
题目描述思路分析采用滑动窗口,窗口有左右边界,先通过扩展右边界找出一个包含T中所有字符的子串,然后收缩左边界,直到不能再收缩。记录此时的子串。然后收缩左边界,继续扩展右边界,直到再找到满足要求的子串,和上次的进行比较,保存更小的子串。返回执行,直到右边界到达S串尾,且左边界不能再收缩。代码public static String minWindow(String s, String t)...原创 2018-12-23 20:44:25 · 128 阅读 · 0 评论