lecode刷题
lecode刷题
baobao1767640830
这个作者很懒,什么都没留下…
展开
-
二叉树的直径
二叉树的解题技巧是,首先判断问题能否划分为子问题、应当划分为什么样的子问题。二叉树直径实际上就是二叉树中的最长路径,我们是可以划分出子问题的:二叉树的最长路径=max{左子树的最长路径,右子树的最长路径,经过根结点的最长路径}其中左子树的最长路径和右子树的最长路径是两个可以递归求解的子问题,那么经过根结点的最长路径如何计算呢?是左子树的深度加上右子树的深度。代入上面的式子得到:二叉树的最长路径=max{左子树的最长路径,右子树的最长路径,左子树的深度+右子树的深度}子树的最大直径、子树的最大深度。这原创 2020-06-03 19:21:51 · 367 阅读 · 1 评论 -
腐烂的橘子
DFS(深度优先搜索)和 BFS(广度优先搜索)。它们各有不同的适应场景。题目要求:返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。实际上就是求腐烂橘子到所有新鲜橘子的最短路径。那么这道题使用 BFS,应该是毫无疑问的了这道题的主要思路是:1.一开始,我们找出所有腐烂的橘子,将它们放入队列,作为第 0 层的结点。2.然后进行 BFS 遍历,每个结点的相邻结点可能是上、下、左、右四个方向的结点,注意判断结点位于网格边界的特殊情况。3.由于可能存在无法被污染的橘子,我们需要记录新鲜橘子的数量。原创 2020-06-03 19:06:31 · 216 阅读 · 0 评论 -
II 和为S的连续正数序列
了解滑动窗口:滑动窗口可以看成数组中框起来的一个部分。在一些数组类题目中,我们可以用滑动窗口来观察可能的候选结果。当滑动窗口从数组的左边滑到了右边,我们就可以从所有的候选结果中找到最优的结果。对于这道题来说,数组就是正整数序列 。我们设滑动窗口的左边界为 i,右边界为j ,则滑动窗口框起来的是一个左闭右开区间 。注意,为了编程的方便,滑动窗口一般表示成一个左闭右开区间。在一开始,i=1,j=1.滑动窗口位于序列的最左侧,窗口大小为零.滑动窗口的重要性质是:窗口的左边界和右边界永远只能向右移动,而不能原创 2020-06-02 19:15:21 · 202 阅读 · 0 评论 -
旋转数组问题
先将整个数组反转,再将数组的前后两半(前 k 个数和后 k 个数)分别反转,就可以实现数组的旋转了。三次反转(reverse)操作的过程如下图所示:public void rotate(int[] nums, int k){ int N = nums.length; reverse(nums, 0, N); reverse(nums, 0, k); reverse(nums, k, N);};void reverse(int[] nums, int begin, in原创 2020-06-02 18:51:17 · 184 阅读 · 0 评论 -
链表排序
总体思想为以上三部分。下面分别讲述:1.划分:这个操作实际上可以拆分为两个基本操作:a.寻找链表的中点b.删除链表中点左侧的指针,将链表断开寻找链表中点的操作,我们在链表快慢指针的文章中讲过,使用一快一慢两个指针遍历链表即可。删除链表指针,实际上和删除链表结点类似。我们在链表遍历框架的文章中讲过,使用相邻的两个指针一同遍历链表即可。ListNode split(ListNode head){ ListNode fast = head; ListNode slow = he.原创 2020-06-01 19:40:10 · 119 阅读 · 0 评论 -
判断链表中是否存在环
如果链表中不存在环的话,快指针则不会和慢指针指向同一个结点,而是会走到链表结尾。依照这个思路我们可以得到以下的题解代码public boolean hasCycle(ListNode head){ ListNode fast = head; ListNode slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = s原创 2020-05-31 20:44:59 · 137 阅读 · 0 评论 -
寻找链表的倒数第 k 个元素
思路:快慢指针,两个指针速度相同,只是间隔一定距离。快指针先前进 k个元素,然后两个指针同样速度前进。这样当快指针到达链表尾部时,慢指针正好到达链表的倒数第k 个元素public ListNode removeNthFromEnd(ListNode head, int k){ ListNode fast = head; for(int i = 0; i < k; i++){ fast=fast.next; } ListNode curr = head;原创 2020-05-31 20:41:13 · 139 阅读 · 0 评论 -
寻找链表中点
链表数据类型的特点决定了它只能单向顺序访问,而不能逆向遍历或随机访问(按下标访问)。很多时候,我们需要使用快慢指针的技巧来实现一定程序的逆向遍历,或者减少遍历的次数。这就是为什么快慢指针常用于链表问题。快指针一次前进两个结点,速度是慢指针的两倍。这样当快指针到达链表尾部时,慢指针正好到达的链表的中部。过程如下方动图所示。public ListNode middleNode(ListNode head) { ListNode fast = head; ListNode slow = h原创 2020-05-30 21:52:22 · 499 阅读 · 0 评论 -
盛最多水的容器
如果选择固定一根柱子,另外一根变化,水的面积会有什么变化吗?推测结论:1.当前柱子是最两侧的柱子,水的宽度 为最大,其他的组合,水的宽度都比这个小。左边柱子较短,决定了水的高度为 3。2.如果移动左边的柱子,新的水面高度不确定,一定不会超过右边的柱子高度 7。3.如果移动右边的柱子,新的水面高度一定不会超过左边的柱子高度 3,也就是不会超过现在的水面高度结论:由此可见,如果固定左边的柱子,移动右边的柱子,那么水的高度一定不会增加,且宽度一定减少,所以水的面积一定减少。这个时候,左边的柱子和任意.原创 2020-05-30 21:45:03 · 152 阅读 · 0 评论 -
给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数(不可以重复使用同一个数)
有序这个条件,你可能首先想到的是二分查找。但是仔细一想,需要固定一个数,对另一个数进行二分查找样时间复杂度是较高。使用双指针解法:public int[] twoSum(int[] nums, int target) {int i=0;int j=nums.length-1; while(i<j){ int sum=nums[i]+nums[j]; if(sum < target){ i++; } else if((sum >原创 2020-05-28 21:55:40 · 1368 阅读 · 0 评论 -
回溯算法
二叉树的遍历过程:以 Path Sum 为例为了最终输出所有可能的路径,我们需要在遍历时记录当前路径,当发现路径满足条件时,就将路径保存下来。路径遍历的顺序实际上就是 DFS 的顺序。当 DFS 进入一个结点时,路径中就增加一个结点;当 DFS 从一个结点退出时,路径中就减少一个结点。下面的 GIF 动图展示了这个过程。回溯算法的递归与遍历策略回溯(backtracking) 实际上就是“撤回一步”的意思。而在二叉树的 DFS 遍历中,从一个结点退出就是一种回溯。回溯法和 DFS 是息息相关的。例如原创 2020-05-27 21:51:52 · 290 阅读 · 0 评论 -
给定一个二叉树和一个目标和,判断该树中是否存在根结点到叶结点的路径
题目:给定一个二叉树和一个目标和,判断该树中是否存在根结点到叶结点的路径,这条路径上所有结点值相加等于目标和。返回 true 或者 false。1.了解二叉树的遍历框架说到二叉树的遍历框架,很多人的脑海里立马蹦出来的就是前序、中序和后序遍历。但是机械地记住前中后序遍历没有太大意义,我们首先要掌握的是二叉树的递归思想递归有两大要点:反复调用自身终止条件二叉树结构上进行递归,则这两大要点变为:递归调用自己两个子树在叶结点处终止递归调用子树的部分是重点。我们需要保证在子树上求解的是与原问题相同原创 2020-05-26 19:48:29 · 2616 阅读 · 0 评论 -
反转一个单链表
1.单链表这样一个相对“简陋”的数据结构,实际上就是为了考察面试者指针操作的基本功。2.如何才能简洁明了地解决单链表问题呢?实际上很多链表题目都是类型化的,都可以归结为链表的遍历,以及在遍历中做插入和删除操作。我们可以使用链表遍历的框架来解题a.了解链表遍历框架:当删除链表结点时,既需要访问当前结点,也需要访问前一个结点。既然这样,我们不妨使用两个指针来遍历链表,curr 指针指向当前结点,prev 指针指向前一个结点。这样两个指针的语义明确,也让你写出的代码更易理解。b.单步操作是“反转 pre原创 2020-05-26 19:33:39 · 169 阅读 · 0 评论
分享