
leetcode
我会jvav啊
此人很懒,已经转行摸鱼了
展开
-
LeetCode114二叉树展开为链表(递归)
题目递归保存当前结点的左右结点,遇到的左结点直接拼到右节点,左节点遍历完之后回溯,找到当前最底层的右结点,再将右节点拼接过去。两个版本一 有返回值 public TreeNode build(TreeNode root){ if (root == null) return null; TreeNode left = root.left; TreeNode right = root.right; root.left = null;原创 2021-03-22 22:25:32 · 178 阅读 · 0 评论 -
LeetCode72编辑距离(dp)
题目开始以为不是dp 后来看了下题解dp[i][j] 代表word1截止到第i个字符转换成word2截止到第j个字符需要几步变换状态方程if(word1[i] == word2[j]) dp[i][j] = dp[i-1][j-1] //无需操作else dp[i][j] = Math.min(Math.min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;dp[i][j-1]+1 代表word1截止到第i个转换成word2第j-1个需要的次数然后再插入第j个字原创 2021-03-22 17:32:21 · 154 阅读 · 0 评论 -
LeetCode438找到字符串中所有字母异位词(字符串哈希)
题目链接字符串哈希 对哈希的方法还是有点理解的不好 public List<Integer> findAnagrams(String s, String p) { int phash = gethash(p); int plen = p.length(); int slen = s.length(); List<Integer> list = new ArrayList<>();原创 2021-03-15 21:21:52 · 143 阅读 · 0 评论 -
LeetCode49字母异位词分组(手写字符串hash)
题目链接字符串哈希 越散列越好哈希算法要求将abc和bac我们认为他们是一类的字符串,计算得到的哈希值(特征值)应该一样,abc和bcd不是同一类,计算得到的哈希值应该不一样,这就是我们手写哈希算法的要求。简单例子将abc和bac映射成一个哈希值,简单映射 我们可以 把 a + b + c = 97 + 98 + 99 = 294作为哈希值, 和 b + a + c = 98 + 97 + 99 = 294. 显然两个哈希值一样,这也是我们想要的结果,将这两个字符串映射成哈希值相同的结果,是我们原创 2021-03-15 20:47:25 · 123 阅读 · 0 评论 -
LeetCode538把二叉搜索树转换为累加树(递归 反中序遍历)
题目链接二叉累加树的定义是每个节点等于所有大于自己的节点之和。首先二叉搜索树的中序遍历是绝对升序的 为012345678这是我们如果反中序遍历(右根左) 会得到876543210这是如果把已经遍历到的值累计加到下一个遍历的节点上就可以得到二叉累加树 int sum = 0;//维护一个全局的和 public TreeNode convertBST(TreeNode root) { dismid(root); return root; }原创 2021-03-13 22:02:07 · 98 阅读 · 0 评论 -
LeetCode543二叉树的直径(递归)
题目链接题目乍一看以为是在求二叉树深度,但其实是求所有几点中左右子树深度和最大的值因为题目中说了这条最长路径可能不经过根节点 下面让我们看两组例子那么现在只需要在二叉树的深度上进行一点小变形就能做出来了每次递归的时候维护一个左右子树深度和的最大值即可 int res = 0; public int diameterOfBinaryTree(TreeNode root) { getdeep(root); return res; } p原创 2021-03-13 17:36:34 · 126 阅读 · 0 评论 -
LeetCode581最短无序连续子数组(排序 或者 思维)
题目链接最简单的就是排序然后找到正向遍历第一个不相同的元素和逆向遍历第一个不相同的元素时间是Onlogn进阶写法可以On先正向遍历找到打破升序后最小的元素 再逆向遍历找到打破降序后的最大元素然后再找到上述最小元素和最大元素该放置的位置 public int findUnsortedSubarray(int[] nums) { int vis1 = 0 ,vis2 = 0; int min = 100005 ,max = -100005;原创 2021-03-13 17:06:58 · 122 阅读 · 0 评论 -
LeetCode647回文子串(dp)
题目链接之前做过一个类似的是求最长的回文串 这个一个思路首先每一个字符自己都回文 然后再判断有多少哥回文串回文串的判断还是用dp方程为 dp[i][j] = s[i] == s[j] AND ( j-i+1<4 OR dp[i+1][j-1] )详细讲解如下1.我们首先确定状态分解成子问题 dp[i][j]代表的意思是区间i-j是否回文 而i-j回文需要满足s[i]==s[j]并且dp[i+1][j-1]也是回文或者字符串长度小于4 格式为 a aa aba 一定也回文2.写出状态转移原创 2021-03-13 14:59:51 · 121 阅读 · 0 评论 -
LeetCode739每日温度(思维或单调栈)
题目链接之前没接触过单调栈的题以为是思维题想了一个思路 时间超越100%倒着遍历 倒数第一个为0依次遍历的时候先和第i+1的元素比较,如果第i+1个元素大于当前元素则答案数组赋值为1如果第i+1个元素不比自己大,找比第i+1个元素大的值,直到找到第一个大于第i个元素的元素或者某个res[vis] = 0 则赋值为0 说明没有比当前元素大的值了。 public int[] dailyTemperatures(int[] T) { int len = T.length;原创 2021-03-11 15:38:55 · 140 阅读 · 0 评论 -
LeetCode494目标和(dfs)
题目想不到dp方程怎么写 写一发搜索试试 还好过了public class LeetCode494 { int res = 0; public int findTargetSumWays(int[] nums, int S) { dfs(nums,S,0,0); return res; } private void dfs(int[] nums, int k, int sum, int step){ if (step ==原创 2021-03-11 14:05:27 · 103 阅读 · 0 评论 -
LeetCode437路径总和 III(前缀和+哈希表+递归)
题目链接刚做完一个前缀和的题目以为能切出来 最后还是看了题解 手动狗头 递归思想没想到前缀和和哈希表就不用多说了,用哈希表存到达当前结点前路径上的所有前缀和值和数量当匹配完这个结点时可以巧妙的都运用回溯再回到上一个结点并且删掉该结点更新的前缀和即可因为思想是前缀和,所以不属于前缀的,我们就要去掉他/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode原创 2021-03-10 21:25:43 · 258 阅读 · 0 评论 -
LeetCode560和为K的子数组(前缀和+哈希表优化)
题目裸的前缀和进行相减的判断直接就可以过 不过时间复杂度非常大朴素版本 public int subarraySum(int[] nums, int k) { int cnt = 0; int presum[] = new int[nums.length+1]; presum[0] = 0; for (int i = 1; i < nums.length+1; i++) {//前缀和 presum[i原创 2021-03-10 19:23:55 · 151 阅读 · 0 评论 -
LeetCode416分割等和子集(01背包)
题目01背包问题参考动态规划详解-背包问题(超简单理解加区分01背包和完全背包)首先判断加和后的奇偶性 如果为奇数无法划分。背包的目标值是和的一半,如果能正好装满和的一半则能划分此时用boolen类型的dp数组,dp[0]赋为true,然后01背包模板dpdp方程为 dp[j] = dp[j] 或者 dp[j-nums[i]]; 如果之前dp[j]为true则为true,或者dp[j-nums[i]]可以正好装满当前dp[j]也为true public boolean canPartit原创 2021-03-09 22:24:57 · 156 阅读 · 0 评论 -
LeetCode617合并二叉树(递归)
题目去hxd寝室溜达非得让我做下这题 卡了一会做出来了让他心态崩了hhh以root1为答案树进行返回 public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { if (root1 == null) return root2; if (root2 == null) return root1; root1.val = root1.val + root2.val;//加和原创 2021-03-09 20:08:27 · 85 阅读 · 0 评论 -
LeetCode448找到所有数组中消失的数字(思维 置负数)
题目链接朴素写法 不满足时间On 不过比较容易想到首先预排序然后把第一个元素前大于0小于自己的元素添加进集合然后中间元素进行判断是否等于或者比前一个元素大1 如果不符合条件则说明中间有空缺元素 入集合 最后将最后一个元素后大于本身小于等于数组长度的值入集合class Solution { public List<Integer> findDisappearedNumbers(int[] nums) { if (nums.length == 0) return ne原创 2021-03-09 16:45:35 · 137 阅读 · 0 评论 -
LeetCode406根据身高重建队列(先排序再插入)
题目数对问题的处理方法基本就是对第一维升序排序 第二维降序排序 或者第一维降序 第二维升序 排序后就好好处理很多本题的思路是将个高的排好 然后将个小的挨个插入 插入时候可以保证不会影响到后面个高的 因为他一定比身后个高的小例如// [7,0], [7,1], [6,1], [5,0], [5,2], [4,4]// 再一个一个插入。// [7,0]// [7,0], [7,1]// [7,0], [6,1], [7,1]// [5,0], [7,0], [6,1], [7,1]// [原创 2021-03-09 12:19:12 · 200 阅读 · 0 评论 -
LeetCode394字符串解码(双栈)
题目链接拿到题就知道是用栈但是还是写不出来 参考了题解一个栈用来存数字 一个栈用来存字符串遍历的时候如果遇到数字则转换成真正的数字 每次自乘10是处理两位数以上的数据遍历到’【'时候需要将当前的数字和字符串分别入栈 然后置位0和空(需要new一个新的StringBuffer)遍历到‘】’时先将数字上一个数字出栈,进行cnt*str的操作,然后将上一个字符栈里的字符串出栈进行拼接遍历到字符时直接将该字符追加到当前维护的StringBuffer上。 public String decode原创 2021-03-08 23:05:26 · 143 阅读 · 0 评论 -
LeetCode347前 K 个高频元素(哈希表加优先队列)
题目TopK问题非常常见 今天学习了其中的一种解法 最小堆 也就是优先队列首先我们一遍哈希 存下每个数字出现的次数然后维护一个长度为K的优先队列小于K时直接入队 等于K时判断是否大于队首元素(由于是升序队列所以大于最小的即可) public int[] topKFrequent(int[] nums, int k) { HashMap<Integer,Integer> map = new HashMap<>(); for (int n原创 2021-03-08 21:42:02 · 154 阅读 · 0 评论 -
LeetCode338比特位计数(dp思维)
题目首先最简单的解法就是遍历每个数去转二进制计1的个数在要求时间复杂度为On的情况下需要运用dp思路我们例举一些二进制数可以发现 001 010 011 100 101 110 111 1000 1001…我们可以发现其中的规律 如果当前数为奇数 则1的个数为前一个偶数1的个数+1,如果当前数为偶数 则1 的个数等于 当前数/2 的1的个数 public int[] countBits(int num) { int[] dp = new int[num+1];原创 2021-03-08 20:52:59 · 93 阅读 · 0 评论 -
LeetCode213打家劫舍 II(dp)
题目链接这题和打家劫舍I 的不同点就是成环 头结点偷了尾节点就不能偷,尾节点偷了头结点就不能偷。所以我们需要分段考虑第一段是0~len-2第二段是1~len-1 public int rob(int[] nums) { if (nums.length == 1) return nums[0]; if (nums.length == 2) return Math.max(nums[0],nums[1]); int res = robRange(原创 2021-02-22 22:53:43 · 106 阅读 · 0 评论 -
LeetCode337打家劫舍 III(树形dp)
题目链接第一次接触到树形dp的问题本题对于某个结点进行分类讨论1.当前结点拿,那么当前偷到的价值就是当前结点的价值加上左结点不拿时下面结点提供的价值和右节点不拿时下面结点提供的价值2.当前结点不拿,那么当前偷到的价值就是左结点拿或者不拿的最大价值和右节点拿或者不拿的最大价值之和总结一下当前节点选择偷时,那么两个孩子节点就不能选择偷了当前节点选择不偷时,两个孩子节点只需要拿最多的钱出来就行(两个孩子节点偷不偷没关系)我们使用一个大小为 2 的数组来表示 int[] res = new int原创 2021-02-22 21:58:47 · 133 阅读 · 0 评论 -
LeetCode309最佳买卖股票时机含冷冻期(状态机dp)
题目链接我们目前持有一支股票,对应的「累计最大收益」记为 f[i][0];我们目前不持有任何股票,并且处于冷冻期中,对应的「累计最大收益」记为 f[i][1];我们目前不持有任何股票,并且不处于冷冻期中,对应的「累计最大收益」记为 f[i][2]。这里的「处于冷冻期」指的是在第 ii 天结束之后的状态。也就是说:如果第 i 天结束之后处于冷冻期,那么第 i+1 天无法买入股票。 public int maxProfit(int[] prices) { if (prices.原创 2021-02-22 19:29:28 · 148 阅读 · 0 评论 -
LeetCode300最长递增子序列(dp或纸牌游戏二分)
题目链接朴素解法 dp判断当前数是否可以加在前面的某个上升序列后面 public int lengthOfLIS(int[] nums) { int dp[] = new int[nums.length]; int ans = 0; for (int i = 0; i < nums.length; i++) { dp[i] = 1; for (int j = 0; j < i; j++)原创 2021-02-22 16:24:55 · 402 阅读 · 0 评论 -
LeetCode287寻找重复数(快慢指针 判断环的入口)
题目链接如果不考虑空间O1的话完全可以用hashset 来做这题可以利用快慢指针的思想判断环的起点LeetCode142本题构建链表为 nums[0]一>nums[nums[0]]一>nums[nums[nums[0]]]…当快慢指针相遇时已经在环内了重置慢指针到链表头 然后和快指针一起每次向前走一步,再次相遇就是环的入口 public int findDuplicate(int[] nums) { int fast = nums[0] ,slow = n原创 2021-02-19 22:08:36 · 136 阅读 · 0 评论 -
LeetCode461汉明距离(异或)
题目异或后的数字计算1的个数 public int hammingDistance(int x, int y) { int z = x ^ y; int cnt = 0; while (z != 0){ if (z % 2 == 1) cnt++; z/=2; } return cnt; }原创 2021-02-05 22:40:41 · 228 阅读 · 0 评论 -
LeetCode279完全平方数(完全背包)
题目完全背包思想,每件物品可以拿K个 价值为1 最后希望价值越小越好 public int numSquares(int n) { int[] dp = new int[n+1]; for (int i = 1; i <= (int) Math.sqrt(n) ; i++) { for (int j = i*i; j <= n; j++) { if (dp[j] == 0) dp[j] = dp[原创 2021-02-05 21:05:41 · 123 阅读 · 0 评论 -
LeetCode240搜索二维矩阵 II(思维)
题目一看觉得是二分思想 但是实现起来很复杂 借鉴了题解里的一种方法从右上角出发 比目标值大往左找,比目标值小往下找属实np 主要思想是找一个点能缩小查找区间 左小角也可以 public boolean searchMatrix(int[][] matrix, int target) { int i = 0, j = matrix[0].length-1; while (i<matrix.length && j>=0){原创 2021-02-05 18:17:25 · 97 阅读 · 0 评论 -
LeetCode238除自身以外数组的乘积(思维或双指针)
题目朴素解法 满足时间On 空间不满足O1构造两个数组 一个存前缀积 一个存后缀积 最后两两相乘 public int[] productExceptSelf(int[] nums) { int n = nums.length; int[] l = new int[n]; int[] r = new int[n]; l[0] = 1; r[n-1] = 1; for (int i = 1,j = n原创 2021-02-05 17:17:31 · 96 阅读 · 0 评论 -
LeetCode236二叉树的最近公共祖先(递归)
题目递归思想递归找p和q结点,root.left去找当前根节点的左子树,root.right去找当前根节点的右子树。分为四种情况left和right均为null 说明当前根节点下没有p和q 返回nullleft为null 说明p和q均不在left的子树中 返回rightright为null 说明p和q均不在right的子树中 返回leftleft和right都不为null 说明p和q在当前root的异侧 返回当前root public TreeNode lowestCommonA原创 2021-02-05 15:00:02 · 104 阅读 · 0 评论 -
LeetCode234回文链表(快慢指针)
题目不进阶的话这里我用的是栈解决的 前半段入栈 然后边出栈边和后半段比较 代码比较好些就不贴上来了进阶方法是快慢指针 快指针指向结尾时 慢指针指向中间 过程中反转从头到中间结点这段链表 然后正向的和慢指针接下来指向的后半段链表逐个比较注意一下如果链表长度为奇数 慢指针需要先向后移动一位再比较 将中间数跳过 public boolean isPalindrome(ListNode head) { if (head == null || head.next == null) re原创 2021-02-04 21:10:11 · 109 阅读 · 0 评论 -
LeetCode221最大正方形(dp)
题目链接思路 取左上,上,左 最小值加1 就是当前点的正方形边长 public int maximalSquare(char[][] matrix) { int row = matrix.length; int column = matrix[0].length; int[][] dp = new int[row][column]; int max = 0; for (int i = 0; i < row; i原创 2021-02-03 21:49:43 · 99 阅读 · 0 评论 -
LeetCode215数组中的第K个最大元素(优先队列或排序)
题目链接优先队列实现在线挑选第K大的数利用优先队列入队后自动升序,而我们可以边入队边维护,当队列长度大于k时就出队,遍历到最后队列里第一个数就是第k大的数 public int findKthLargest(int[] nums, int k) { PriorityQueue<Integer> queue = new PriorityQueue<>((a,b) -> a-b); for (int i = 0; i < nums原创 2021-02-03 20:28:37 · 142 阅读 · 0 评论 -
LeetCode207课程表(拓补排序 入度表+BFS)
题目链接最开始暴力写过一发但是太慢了 然后看题解学了拓补排序 入度表+BFS我们使用一个队列来进行广度优先搜索。初始时,所有入度为 00 的节点都被放入队列中,它们就是可以作为拓扑排序最前面的节点,并且它们之间的相对顺序是无关紧要的。在广度优先搜索的每一步中,我们取出队首的节点 uu:我们将 uu 放入答案中;我们移除 uu 的所有出边,也就是将 uu 的所有相邻节点的入度减少 11。如果某个相邻节点 vv 的入度变为 00,那么我们就将 vv 放入队列中。在广度优先搜索的过程结束后。如果答原创 2021-02-03 19:39:36 · 177 阅读 · 0 评论 -
LeetCode226翻转二叉树(递归)
题目链接第一道思路特别清晰的递归递归找左和右 然后交换 public TreeNode invertTree(TreeNode root) { if (root == null) return root; TreeNode left = invertTree(root.left); TreeNode right = invertTree(root.right); root.left = right; root.ri原创 2021-02-02 23:27:14 · 112 阅读 · 0 评论 -
LeetCode283移动零(移动补零)
题目链接移动补0 public void moveZeroes(int[] nums) { int cnt = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] != 0) nums[cnt++] = nums[i]; } while (cnt < nums.length) nums原创 2021-02-02 22:32:21 · 114 阅读 · 0 评论 -
LeetCode206反转链表(头插法逆置)
题目链接将原链表头结点指向null 从第二个结点到结尾一次插入到链表头 public ListNode reverseList(ListNode head) { if (head == null || head.next == null) return head; ListNode second = head.next;//保存头结点后面的所有结点 head.next = null;//头结点变尾节点 ListNode dummyH原创 2021-02-02 21:25:07 · 272 阅读 · 0 评论 -
LeetCode200岛屿数量(bfs)
题目链接找1当做起点,并且该起点可以延伸到的1都置位0 public int numIslands(char[][] grid) { int cnt = 0; int[][] dir = new int[][]{{0,1},{0,-1},{1,0},{-1,0}}; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length原创 2021-02-02 20:25:11 · 124 阅读 · 0 评论 -
LeetCode198打家劫舍(dp)
题目链接开始离题解只差一步,不过被自己给否定了,想出了一个方程就是该点只可能从上一个点过来不偷该房子的价值和从前两个点的位置直接过来并且拿该点的值,或者从前三个点的位置过来拿该点的值,方程有点复杂不过还是过了class Solution { public int rob(int[] nums) { int n = nums.length; if (n == 0) return 0; if (n == 1) return nums[0];原创 2021-02-02 18:25:01 · 143 阅读 · 0 评论 -
LeetCode169多数元素(摩尔投票或排序)
题目链接投票算法每个人都可以是候选人,自己选自己是cnt++,一旦不是自己就cnt–,等于0时更换新的候选人,因为存在多数,则最后剩下的候选人一定是多数。因为多数元素和其他元素两两抵消,最后还剩多数元素 public int majorityElement(int[] nums) { int more = nums[0]; int cnt = 1; for (int i = 1; i < nums.length; i++) {原创 2021-02-01 20:00:06 · 108 阅读 · 0 评论 -
LeetCode160相交链表(双指针)
题目链接算出两个链表长度的差值,让长链表的指针先走差值个结点,然后遍历相同点即为相交点。 public ListNode getIntersectionNode(ListNode headA, ListNode headB) { int cnt1 = 0 ,cnt2 = 0; ListNode p1 = headA ,p2 = headB; while (p1 != null || p2 != null){//计算两个链表长度原创 2021-02-01 17:04:56 · 96 阅读 · 0 评论