数据结构与算法
轮子飞了
这个作者很懒,什么都没留下…
展开
-
树的遍历:144. 二叉树的前序遍历
给你二叉树的根节点root,返回它节点值的前序遍历。方法一:递归思路与算法首先我们需要了解什么是二叉树的前序遍历:按照访问根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程。定义 preorder(root) 表示当前遍历到 root 节点的答案。按照定义,我们只要首先将 root 节点的值加入答案,然后递归调用 preorder(root.lef...原创 2020-12-08 11:26:07 · 281 阅读 · 0 评论 -
树的遍历:110. 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。示例 1:输入:root = [3,9,20,null,null,15,7]输出:trueclass Solution { public boolean isBalanced(TreeNode root) { if (root == null) { return true; ..原创 2020-11-11 17:41:54 · 136 阅读 · 0 评论 -
树的遍历:102. 二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。示例:二叉树:[3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7返回其层次遍历结果:[ [3], [9,20], [15,7]]class Solution { public List<List<Integer>> levelOrder(TreeNode root) {...原创 2020-11-10 16:44:13 · 250 阅读 · 1 评论 -
树的遍历:给定一个二叉树的根节点 root ,返回它的 中序 遍历。
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<Integ.原创 2020-11-10 16:39:41 · 2445 阅读 · 1 评论 -
分治法/二分法:34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。你的算法时间复杂度必须是O(log n) 级别。如果数组中不存在目标值,返回[-1, -1]。示例 1:输入: nums = [5,7,7,8,8,10], target = 8输出: [3,4]示例2:输入: nums = [5,7,7,8,8,10], target = 6输出: [-1,-1]在二分查找法中使用 if(target >= nums[...原创 2020-11-10 15:40:14 · 287 阅读 · 0 评论 -
二分法:33. 搜索旋转排序数组
给你一个升序排列的整数数组 nums ,和一个整数 target 。假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组[0,1,2,4,5,6,7]可能变为[4,5,6,7,0,1,2] )。请你在数组中搜索target ,如果数组中存在这个目标值,则返回它的索引,否则返回-1。示例 1:输入:nums = [4,5,6,7,0,1,2], target = 0输出:4示例2:输入:nums = [4,5,6,7,0,1,2], target = 3...原创 2020-11-07 16:07:36 · 50 阅读 · 0 评论 -
分治法/二分法:23. 合并K个升序链表
给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例 1:输入:lists = [[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[ 1->4->5, 1->3->4, 2->6]将它们合并到一个有序链表中得到。1->1->2->3->4->4->5->6一开始数组的规模是6,我们找到中...原创 2020-11-07 15:30:31 · 343 阅读 · 0 评论 -
递归:1325. 删除给定值的叶子节点
给你一棵以root为根的二叉树和一个整数target,请你删除所有值为target 的叶子节点 。注意,一旦删除值为target的叶子节点,它的父节点就可能变成叶子节点;如果新叶子节点的值恰好也是target ,那么这个节点也应该被删除。也就是说,你需要重复此过程直到不能继续删除。示例 1:输入:root = [1,2,3,2,null,2,4], target = 2输出:[1,null,3,null,4]解释:上面左边的图中,绿色节点为叶子节点,且它们的值与...原创 2020-11-07 15:15:41 · 438 阅读 · 0 评论 -
递归:236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉树:root =[3,5,1,6,2,0,8,null,null,7,4]示例 1:输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输出: 3解释: 节点 5...原创 2020-11-07 14:53:51 · 71 阅读 · 0 评论 -
递归:226. 翻转二叉树
翻转一棵二叉树。示例:输入: 4 / \ 2 7/ \ / \1 3 6 9输出: 4 / \ 7 2/ \ / \9 6 3 1class Solution { public TreeNode invertTree(TreeNode root) { //递归函数的终止条件,节点为空时返回 if(root==null) { return null; } //下面三句...原创 2020-11-05 17:44:01 · 114 阅读 · 0 评论 -
递归:104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明:叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7返回它的最大深度3 。/** * Definition for a binary tree node. * public class TreeNode { * int val; * Tree...原创 2020-11-05 17:41:13 · 52 阅读 · 0 评论 -
递归:101. 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。例如,二叉树[1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2/ \ / \3 4 4 3但是下面这个[1,2,2,null,3,null,3] 则不是镜像对称的: 1 / \ 2 2 \ \ 3 3class Solution { public boolean isSymmetric(TreeNode root) { if(root==nul...原创 2020-11-05 16:34:33 · 185 阅读 · 0 评论 -
递归:21. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例:输入:1->2->4, 1->3->4输出:1->1->2->3->4->4递归函数必须要有终止条件,否则会出错; 递归函数先不断调用自身,直到遇到终止条件后进行回溯,最终返回答案。class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode ..原创 2020-11-05 16:15:24 · 126 阅读 · 0 评论 -
堆相关:215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。示例 1:输入: [3,2,1,5,6,4] 和 k = 2输出: 5示例2:输入: [3,2,3,1,2,4,5,5,6] 和 k = 4输出: 4我们可以使用最小堆来解决,一个个遍历原数组的值,添加到堆中,如果堆中元素的个数小于等于k的时候,我们就往堆中添加,添加之后如果堆中元素个数大于k的时候,我们就把最顶端的元素给移除掉,因为是最小堆,所以移除的就是堆中.原创 2020-11-05 16:01:35 · 77 阅读 · 0 评论 -
堆相关:347. 前 K 个高频元素
给定一个非空的整数数组,返回其中出现频率前k高的元素。示例 1:输入: nums = [1,1,1,2,2,3], k = 2输出: [1,2]示例 2:输入: nums = [1], k = 1输出: [1]在这里,我们可以利用堆的思想:建立一个小顶堆,然后遍历「出现次数数组」:如果堆的元素个数小于 kk,就可以直接插入堆中。如果堆的元素个数等于 kk,则检查堆顶与当前出现次数的大小。如果堆顶更大,说明至少有 kk 个数字的出现次数比当前值大,故舍弃当前值;否则,就弹...原创 2020-11-05 15:58:33 · 80 阅读 · 0 评论 -
栈相关:316. 去除重复字母
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters 相同示例 1:输入:s = "bcabc"输出:"abc"示例 2:输入:s = "cbacdcbc"输出:"acdb"class Solution { .原创 2020-10-30 18:02:30 · 74 阅读 · 0 评论 -
栈相关:155. 最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。push(x) —— 将元素 x 推入栈中。pop()—— 删除栈顶的元素。top()—— 获取栈顶元素。getMin() —— 检索栈中的最小元素。示例:输入:["MinStack","push","push","push","getMin","pop","top","getMin"][[],[-2],[0],[-3],[],[],[],[]]输出:[null,null,null,nu...原创 2020-10-30 16:40:28 · 67 阅读 · 0 评论 -
栈相关:32. 最长有效括号
给定一个只包含 '('和 ')'的字符串,找出最长的包含有效括号的子串的长度。示例1:输入: "(()"输出: 2解释: 最长有效括号子串为 "()"示例 2:输入: ")()())"输出: 4解释: 最长有效括号子串为 "()()"public class Solution { public int longestValidParentheses(String s) { int maxans = 0; Deque<Intege...原创 2020-10-30 14:32:34 · 62 阅读 · 0 评论 -
栈相关:20. 有效的括号
给定一个只包括'(',')','{','}','[',']'的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。注意空字符串可被认为是有效字符串。示例 1:输入: "()"输出: true示例2:输入: "()[]{}"输出: true解题思路:特判:过滤空字符串创建一个辅助栈:遍历,对每一个字符进行如下操作:若为左括号,则往栈中存放右括号若为右括号,如果 栈为空 或者 该右括号与取出的栈...原创 2020-10-30 14:09:42 · 89 阅读 · 0 评论 -
数组操作:使数组唯一的最小增量
给定整数数组 A,每次 move 操作将会选择任意A[i],并将其递增1。返回使 A中的每个值都是唯一的最少操作次数。示例 1:输入:[1,2,2]输出:1解释:经过一次 move 操作,数组将变为 [1, 2, 3]。示例 2:输入:[3,2,1,2,1,7]输出:6解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。可以看出 5 次或 5 次以下的 move 操作是不能让数组的每个值唯一的。class Solution { ...原创 2020-10-30 13:47:45 · 187 阅读 · 0 评论 -
数组操作:581. 最短无序连续子数组
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。你找到的子数组应是最短的,请输出它的长度。示例 1:输入: [2, 6, 4, 8, 10, 9, 15]输出: 5解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。我们分别定义为begin 和 end;分两头开始遍历:从左到右维护一个最大值max,在进入右段之前,那么遍历到的nums[i]都是小于max的,我们要求的end就是遍历原创 2020-10-30 10:44:02 · 106 阅读 · 0 评论 -
数组操作:78. 子集
给定一组不含重复元素的整数数组nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。示例:输入: nums = [1,2,3]输出:[ [3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]]回溯:class Solution { public List<List<Integer>> subsets(int[] nums) { int le...原创 2020-10-30 10:29:37 · 77 阅读 · 0 评论 -
数组操作:73. 矩阵置零
给定一个m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。示例1:输入:[[1,1,1],[1,0,1],[1,1,1]]输出:[[1,0,1],[0,0,0],[1,0,1]]我们扫描一遍原始矩阵,找到所有为零的元素。如果我们找到 [i, j] 的元素值为零,我们需要记录下行号 i 和列号 j。用两个 sets ,一个记录行信息一个记录列信息。if cell[i][j] == 0 {...原创 2020-10-29 17:51:54 · 221 阅读 · 0 评论 -
数组操作:54. 螺旋矩阵
给定一个包含m x n个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。示例1:输入:[[ 1, 2, 3 ],[ 4, 5, 6 ],[ 7, 8, 9 ]]输出: [1,2,3,6,9,8,7,4,5]这里的方法不需要记录已经走过的路径,所以执行用时和内存消耗都相对较小首先设定上下左右边界其次向右移动到最右,此时第一行因为已经使用过了,可以将其从图中删去,体现在代码中就是重新定义上边界判断若重新定义后,上下边界交错,表明螺旋矩阵遍历...原创 2020-10-29 17:47:55 · 241 阅读 · 0 评论 -
数字操作:258. 各位相加
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。示例:输入: 38输出: 2解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于2 是一位数,所以返回 2。class Solution { public int addDigits(int num) { if (num < 10) { return num; } int next = 0; ..原创 2020-10-29 17:04:09 · 256 阅读 · 0 评论 -
数字操作:172. 阶乘后的零
给定一个整数 n,返回 n! 结果尾数中零的数量。示例 1:输入: 3输出: 0解释:3! = 6, 尾数中没有零。示例2:输入: 5输出: 1解释:5! = 120, 尾数中有 1 个零.解法一首先肯定不能依赖于把阶乘算出来再去判断有多少个零了,因为阶乘很容易就溢出了,所以先一步一步理一下思路吧。首先末尾有多少个 0 ,只需要给当前数乘以一个 10 就可以加一个 0。再具体对于 5!,也就是 5 * 4 * 3 * 2 * 1 = 120,我们发现结果会有一个 ...原创 2020-10-29 17:01:00 · 415 阅读 · 0 评论 -
数字操作:9. 回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。示例 1:输入: 121输出: trueclass Solution { public boolean isPalindrome(int x) { //边界判断 if (x < 0) return false; int div = 1; //定义div为与x同位数 while (x / div >=.原创 2020-10-29 16:46:02 · 89 阅读 · 0 评论 -
数字操作:7_整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。示例1:输入: 123输出: 321示例 2:输入: -123输出: -321示例 3:输入: 120输出: 21class Solution { public static int reverse(int x) { int rev=0; while(x!=0){ int s=x%10; x=x/10; ..原创 2020-10-29 16:03:19 · 288 阅读 · 0 评论 -
字符串操作:763_划分字母区间
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。示例:输入:S = "ababcbacadefegdehijhklij"输出:[9,7,8]解释:划分结果为 "ababcbaca", "defegde", "hijhklij"。每个字母最多出现在一个片段中。像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。class Solution .原创 2020-10-29 15:38:25 · 121 阅读 · 0 评论 -
字符串操作:14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串""。示例1:输入: ["flower","flow","flight"]输出: "fl"示例2:输入: ["dog","racecar","car"]输出: ""解释: 输入不存在公共前缀。public String longestCommonPrefix(String[] strs) { if(strs.length==0){ return ""; ...原创 2020-10-29 14:32:43 · 129 阅读 · 1 评论 -
快慢指针遍历:876. 链表的中间结点
给定一个头结点为 head的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。示例 1:输入:[1,2,3,4,5]输出:此列表中的结点 3 (序列化形式:[3,4,5])返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。注意,我们返回了一个 ListNode 类型的对象 ans,这样:ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.nex..原创 2020-10-28 14:12:16 · 72 阅读 · 0 评论 -
快慢指针遍历:202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为1,那么这个数就是快乐数。如果 n 是快乐数就返回 True ;不是,则返回 False 。示例:输入:19输出:true解释:12 + 92 = 8282 + 22 = 6862 + 82 = 10012 + 02 + 02 = 1class Solut...原创 2020-10-28 11:21:57 · 65 阅读 · 0 评论 -
快慢指针遍历:141. 环形链表
给定一个链表,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。如果链表中存在环,则返回 true 。 否则,返回 false 。public class Solution { public boolean hasCycle(Li原创 2020-10-27 18:15:56 · 201 阅读 · 0 评论 -
双指针遍历/滑动窗口:209. 长度最小的子数组
给定一个含有n个正整数的数组和一个正整数s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。示例:输入:s = 7, nums = [2,3,1,2,4,3]输出:2解释:子数组[4,3]是该条件下的长度最小的子数组。class Solution { public int minSubArrayLen(int s, int[] nums) { int sum=0; ...原创 2020-10-27 17:42:21 · 209 阅读 · 0 评论 -
双指针遍历/滑动窗口:122. 买卖股票的最佳时机2
给定一个数组,它的第i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例 1:输入: [7,1,5,3,6,4]输出: 7解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股..原创 2020-10-27 15:56:45 · 150 阅读 · 0 评论 -
双指针遍历/滑动窗口:121. 买卖股票的最佳时机
给定一个数组,它的第i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。注意:你不能在买入股票前卖出股票。示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。...原创 2020-10-27 15:51:52 · 141 阅读 · 0 评论 -
双指针遍历/滑动窗口:42. 接雨水
给定n个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。示例 1:输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。示例 2:输入:height = [4,2,0,3,2,5]输出:9class Solution { public int t...原创 2020-10-27 15:24:03 · 118 阅读 · 0 评论 -
双指针遍历/滑动窗口:26. 删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。示例1:给定数组 nums = [1,1,2],函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。你不需要考虑数组中超出新长度后面的元素。示例2:给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, ...原创 2020-10-27 11:38:11 · 104 阅读 · 0 评论 -
双指针遍历/滑动窗口:16. 最接近的三数之和
给定一个包括n 个整数的数组nums和 一个目标值target。找出nums中的三个整数,使得它们的和与target最接近。返回这三个数的和。假定每组输入只存在唯一答案。示例:输入:nums = [-1,2,1,-4], target = 1输出:2解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。class Solution { public int threeSumClosest(int[] nums, int target) ...原创 2020-10-26 19:31:28 · 79 阅读 · 0 评论 -
双指针遍历/滑动窗口:15. 三数之和
给你一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,使得a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。注意:答案中不可以包含重复的三元组。示例:给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组集合为:[ [-1, 0, 1], [-1, -1, 2]]class Solution { public List<List<Integer>> ...原创 2020-10-26 19:06:45 · 62 阅读 · 0 评论