力扣刷题思考
文章平均质量分 65
丢丢diu丢
CSDN,做笔记用的……
展开
-
背包问题——01—完全—多重—混合
背包问题 4种类型原创 2022-08-14 11:27:40 · 398 阅读 · 1 评论 -
力扣树——满二叉树、完全二叉树、平衡二叉树、二叉搜索树、最优二叉树、红黑树
1.满二叉树深度为h,那节点数为:2^h-12.完全二叉树深度为h,那么前h-1层都是满的,只有第h层不满,而且是从左向右紧密排列的。3.平衡二叉树1.它可以是1棵空树;2.首先它是二叉搜索树,而且它的左右子树的深度之差绝对值不能超过1;4.二叉搜索树1.它可以是空树2.若不空,那么它中序遍历(左中右)必须是严格递增序列,不存在相同的元素;5.最优二叉树给定N个权值作为N个叶子节点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称哈夫曼树。哈夫曼原创 2021-09-16 22:04:50 · 364 阅读 · 0 评论 -
按位十进制运算——字符串相加、字符串相乘
415. 字符串相加题目分析1.把两个字符串,从低位开始,依次相加。相当于从字符串从后向前遍历2.注意进位问题class Solution { public String addStrings(String num1, String num2) { int len1 = num1.length()-1; int len2 = num2.length()-1; int carry = 0; StringBuffer res原创 2021-09-14 00:47:40 · 344 阅读 · 0 评论 -
力扣刷题——位运算—只出现1次的数字
260. 只出现一次的数字 IIIclass Solution { public int[] singleNumber(int[] nums) { int ret = 0; for (int i = 0; i < nums.length; i++) { ret ^= nums[i]; } int div = 1; 假设两个数是 a、b int a=0;原创 2021-09-12 18:24:06 · 129 阅读 · 0 评论 -
A_力扣刷题列表
0802—动态规划1300. 最长递增子序列354. 俄罗斯套娃信封问题剑指 Offer 42. 连续子数组的最大和剑指 Offer II 095. 最长公共子序列72. 编辑距离516. 最长回文子序列0803—动态规划21312. 让字符串成为回文串的最少插入次数312. 戳气球416. 分割等和子集322. 零钱兑换518. 零钱兑换 II3.3.二叉搜索树操作集锦98. 验证二叉搜索树700. 二叉搜索树中的搜索701. 二叉搜索树中的插入操作450. 删除二叉搜索原创 2021-08-28 21:55:08 · 247 阅读 · 0 评论 -
0803—动态规划2
0.前言动态规划的步骤是什么?1.找到状态、选择。状态,是在变化的东西;选择,是你可以选择的东西。2.明确dp数组的含义3.寻找状态转移方程4.如何选择遍历方向?遍历时的2个注意事项:(1)、所需状态必须是已经计算出来的;(2)、遍历的终点必须是存储返回结果的位置。1. 让字符串成为回文串的最少插入次数...原创 2021-08-06 00:39:24 · 116 阅读 · 0 评论 -
力扣多线程题目1——synchronized实现
1114. 按序打印1.题目分析无论多个线程先调用哪个方法,总是保证:first先执行、second次之、third最后;synchronized加锁,配合标志位进行实现2.代码class Foo { 1.first执行完的标志位 private boolean firstFinised = false; 2.second执行完的标志位 private boolean secondFinised = false; 3.synchronized 锁住的对原创 2021-08-15 21:51:17 · 290 阅读 · 0 评论 -
5.10.如何调度考生的座位
855. 考场就座1.题目分析——线段切分法遇到动态过程中取最值的问题,肯定是要使用有序数组,常用的数据结构就是二叉堆、平衡二叉搜索树。1.本问题就是寻找某两个学生p、q为端点的线段,找出最长的线段,从中间切分开;2.建立TreeSet<int []>数据结构,存储这样的线段,按线段长度升序排列,长度相同则按左侧索引降序;int[]是一个含有两个元素的数组,分别是线段的左、右端点p、q;3.建立Map<Integer,int[]> startMap、Map<In原创 2021-08-14 21:48:24 · 110 阅读 · 0 评论 -
5.9.括号的合法性——使用栈
20. 有效的括号1.题目分析可以考虑使用栈,左括号直接进栈,一旦右括号出现,检查栈顶元素是否与之匹配最后,只有栈为空才说明全部匹配。2.代码class Solution { public boolean isValid(String s) { int len = s.length(); if (len % 2 == 1) return false; Stack<Character原创 2021-08-14 13:53:20 · 115 阅读 · 0 评论 -
5.9.贪心算法做区间调度:不重叠区间个数、最少的箭射气球
1.区间调度问题设计一个算法,算出最多有多少个互不相交的区间?eg:二维数组intvs = [[1,3],[2,4],[3,6]];最多有两个不相交区间,即[1,3]和[3,6]。1.题目分析区间[start, end]1.先把区间按end的升序进行排列;2.从前向后选择时,start >= 当前preEnd 的说明是不重叠区间,res+1,然后更新preEnd = 当前end2.代码class Solution { public int intervalSchedule(原创 2021-08-14 13:07:33 · 151 阅读 · 0 评论 -
5.7.贪心思想玩跳跃游戏——贪心算法、贪心选择算法
55. 跳跃游戏1.题目分析——贪心算法思路——时间复杂度-N,空间复杂度-1每一步都计算从当前位置最远能够跳到哪里。如果当前所到达的最远距离farthest不超过当前位置i,那么就说明前进不了了,false;只有当可到达的最远距离farthest >= 最后一个元素的位置len-1时,true。2.代码class Solution { public boolean canJump(int[] nums) { if (nums == null || nums.原创 2021-08-14 11:20:54 · 208 阅读 · 0 评论 -
5.6.最长回文子串——核心:中心扩散思想
5. 最长回文子串1.题目分析寻找回文串的核心思想是,从中间向两边扩散;注意:要想取处String的start~end下标的局部串,必须这样写:s.substring(start,end+1);2.代码class Solution { public String longestPalindrome(String s) { int start = 0, end = 0; for (int i = 0; i < s.length(); i++) {原创 2021-08-13 22:29:17 · 110 阅读 · 0 评论 -
5.5.如何删除有序数组、链表的重复元素
26. 删除有序数组中的重复项1.题目分析要求原地删除,不可以使用辅助数组;快慢指针,slow指针在后,fast指针在前探路;只有当nums[slow] != nums[fast]时,slow++;并且为移动后的nums[slow]赋值nums[fast]的值,用不重复的元素 覆盖 当前重复的元素,然后fast++,继续前行。2.代码class Solution { public int removeDuplicates(int[] nums) { if (nums原创 2021-08-13 21:25:02 · 81 阅读 · 0 评论 -
5.4.接雨水问题—3种解法:暴力、备忘录、双指针
42. 接雨水1.暴力解法—时间复杂度-N² 空间复杂度-1i位置能装的水量,是其左边最高得柱子left_max,右边最高的柱子right_max,取较小的那个min(left_max,right_max) - i的高度,即可求得。class Solution { public int trap(int[] height) { int res = 0; int len = height.length; 因为数组左右两边的位置不可能存水原创 2021-08-13 20:27:22 · 183 阅读 · 0 评论 -
5.2-5.4:寻找素数、快速横幂运算、二分搜索解决吃香蕉、运货问题
204. 计数质数什么是质数?(素数)一个数如果只能被1和它自身整除,那他就是。1.题目分析建立辅助函数isPrime(int n),来判断一个数n是否为素数。 public boolean isPrime(int n){ for (int i = 2; i*i <= n; i++) { 当有其他的整数因子时 if (n % i == 0) return false; } return true;}注意到,为原创 2021-08-12 22:57:07 · 254 阅读 · 0 评论 -
4.9.前缀和解决子数组问题——优化过程
前缀和可以用来干嘛呢?比如:给你一个成绩表,让你计算不同分数段的人数的百分比。则:count[I]-count[j-1]:表示 j ~ i 分数段有多少人。int[] scores; 存储所有同学的分数int[] count = new int[100+1]; 满分100分 记录得各分数的人数for (int score: scores) { count[score]++;} 构造前缀和for (int i = 1; i < count.length; i++) {原创 2021-08-11 22:57:39 · 88 阅读 · 0 评论 -
4.5.2Sum、3Sum、4Sum、100Sum、nSum问题
1.两数之和——最小时间复杂度为N1.题目分析1.数组中存在两个数,和为target,返回这两个数的下标;2.可以考虑使用hashmap,key为该数,value为该数的下标;3.这个判断条件很重要:map.containsKey(target-nums[i])。1.5.附加思考:如果数组是有序的可以考虑双指针方法。2.代码class Solution { public int[] twoSum(int[] nums, int target) {原创 2021-08-11 21:36:04 · 115 阅读 · 0 评论 -
4.2-4.3.回溯的最佳实践:解数独、括号生成、
37. 解数独1.题目分析2.代码22. 括号生成原创 2021-08-08 22:01:55 · 78 阅读 · 0 评论 -
4.1.回溯算法解决子集、组合、排列问题
78. 子集1.题目分析采用回溯算法,注意在backTrack()函数中,进行回溯时必须传入i+1,而不是index+1,因为没有涉及元素的顺序问题,因为在子集中,[1,2]和[2,1]是一样的2.代码class Solution { List<List<Integer>> res; public List<List<Integer>> subsets(int[] nums) { res = new ArrayList原创 2021-08-08 20:57:00 · 122 阅读 · 0 评论 -
3.10.反转链表:全部、前n个、每k个1组反转
剑指 Offer II 024. 反转链表1.题目分析——重点分析递归实现在后序遍历的地方进行处理。2.代码递归实现class Solution { public ListNode reverseList(ListNode head) { return reverse(head,null); } public ListNode reverse(ListNode node,ListNode pre){ 到了链表结尾原创 2021-08-08 15:07:43 · 524 阅读 · 0 评论 -
3.9.如何判断回文链表
剑指 Offer II 027. 回文链表1.题目分析以快慢指针方法为例——空间复杂度为1,时间复杂度为N1.mid指针每次走1步,fast指针每次走2步,当fast到最后时,mid正好走到链表中间(链表节点数奇偶先不谈)2.反转mid之后的链表,返回头节点rev;3.slow、rev按照回文的规则进行比较,看整条串是否为回文串。2.代码快慢指针class Solution { public boolean isPalindrome(ListNode head) {原创 2021-08-08 00:48:05 · 105 阅读 · 0 评论 -
3.8.特殊数据结构——单调队列
1.什么是单调队列?就是一个队列,只是使用了一点巧妙的方法,使得队列中的元素全都是单调的。239. 滑动窗口最大值1.题目分析——建立单调队列辅助即可单调队列:push入新元素时,要把新元素前边比它小的元素都删掉;pop(int num)出元素时,只要队首元素跟num相等,就删除队首元素;max(),可以获取队列中最大的元素,其实就是队首元素。 public class DanLink{ private LinkedList<Integer> q =原创 2021-08-07 22:59:25 · 94 阅读 · 0 评论 -
3.7.特殊数据结构——单调栈
496. 下一个更大元素 I1.题目分析1.先把nums2数组对应元素的最大值求出来,再处理nums1数组。使用单调栈,从前向后,把没有找到比自己大的数入栈,直到找到一个数比栈顶的数大,把栈顶出栈,再比较新栈顶是否依然比当前元素大?是,则出栈;不是,则向下遍历。2.再对nums1遍历,把符合条件的存入新数组。2.代码class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) {原创 2021-08-07 19:27:53 · 108 阅读 · 0 评论 -
3.6.Git原理之二叉树的最近公共祖先
236. 二叉树的最近公共祖先1.题目分析1.可以考虑递归的方式,考虑3种情况:情况1:p、q存在于以node为根的树中,则返回node;情况2:p、q都不在以node为根的树中,则返回null;情况3:p、q只有1个存在于以node为根的树中,则返回p、q中存在的那个;算法使用了后序遍历:所以是一种自底向上的遍历方法,可以保证p、q第一次会合的地方就是最近公共祖先。2.代码class Solution { public TreeNode lowestCommonAncesto原创 2021-08-07 16:22:46 · 182 阅读 · 0 评论 -
3.5.各种框架序列化、反序列化二叉树
297. 二叉树的序列化与反序列化1.题目分析本题目可以采用前中后序遍历,层序遍历,其中一个就可以了;以前序遍历为例进行讲解1.序列化,通过前序遍历把个节点的value保存到字符串中,各节点之间用 “,” 分隔,空节点null用符号#代替2.反序列化,把字符串重新构造成树,先把字符串转为数组存到LinkList中,然后按照前序遍历的顺序构建树,在此过程中LinkList中的数据从前边开始移除;2.代码class Codec { 代替空节点null String NULL原创 2021-08-07 15:30:28 · 80 阅读 · 0 评论 -
3.4.完全二叉树节点数为什么这么难算?
1.满二叉树、完全二叉树222. 完全二叉树的节点个数1.题目分析1.普通树的节点数需要递归遍历全部的,所以复杂度为N2.满二叉树只需要求出树深度h,再用公式:深度 = 2^h - 1 即可,时间复杂度:logN while(root!=null){ root = root.left h++; // 算出深度即可 }3.完全二叉树则可以借鉴二者合体,时间复杂度:logN * logN因为root根节点的有一棵子树一定是满的,会停止递归;算法的递归深度就是树高原创 2021-08-07 00:50:00 · 112 阅读 · 0 评论 -
3.3.二叉搜索树操作集锦
1.什么是二叉搜索树?它的中序遍历(左、根、右),是严格的递增序列它的逆中序遍历(右、根、左),是严格的递减序列2.本文涉及的力扣题目验证二叉搜索树二叉搜索树中的搜索二叉搜索树中的插入操作删除二叉搜索树中的节点98. 验证二叉搜索树1.题目分析只要中序遍历不是严格的递增序列就不是!为什么下列代码中,pre是long型?因为在输入[-2147483648] 这个的时候,正好是Integer.MIN_VALUE,会产生误判,要让pre足够的小才行。2.代码clas原创 2021-08-05 23:16:13 · 72 阅读 · 0 评论 -
0802—动态规划1
0.前言动态规划的步骤是什么?1.找到状态、选择。状态,是在变化的东西;选择,是你可以选择的东西。2.明确dp数组的含义3.寻找状态转移方程4.如何选择遍历方向?遍历时的2个注意事项:(1)、所需状态必须是已经计算出来的;(2)、遍历的终点必须是存储返回结果的位置。1.最长递增子序列1.题目分析(1).明确dp[]数组的含义:dp[i]表示当数组以nums[i]结尾时,最长的递增子序列是多少;(2).确定base case:dp[]数组初始化为1,因为就算只取nums[i]这1个元素,也原创 2021-08-03 00:10:15 · 101 阅读 · 0 评论 -
力扣刷题——对map进行key、value的升、降序排列
import java.util.*;public class Main { public static void main(String[] args) { Map<Integer,Integer> sortedMap = new HashMap<>(); sortedMap.put(1,20); sortedMap.put(2,30); sortedMap.put(3,10); sorte原创 2021-04-18 13:21:47 · 147 阅读 · 0 评论 -
力扣—二叉树前中后遍历:递归+迭代
1.前序遍历1.递归public List<Integer> preOrder(TreeNode root){ List<Integer> list = new LinkedList<>(); if(root==null){ return list; } list.add(root.val); list.addAll(preOrder(root.left));原创 2021-04-16 11:06:19 · 131 阅读 · 0 评论 -
力扣刷题思考——3数之和
1.三数之和15. 三数之和给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。1.解题思路(迭代+快慢指针)0.先把数组进行升序排列,Arrays.sort(nums);1.建立3个指针,first、second、third,(以下使用first、second、third代替nums[first]、nums[second]、nu原创 2021-04-15 16:43:17 · 108 阅读 · 0 评论 -
力扣刷题——岛屿问题DFS
1.岛屿数量200. 岛屿数量给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。1.解题思路:深度优先搜索1.岛屿四面环水,分为两种情况,1.矩阵中的显式分割水,2.矩阵外越界的隐式分割水;2.只要被水分隔开,那么对元素1的深度优先搜索就会被隔断,如下图所示;3.所以深度优先搜索的终止条件就是:1.所到达位置,元素为0、2.越过原创 2021-04-13 16:44:50 · 598 阅读 · 0 评论 -
力扣刷题——LRU缓存机制
1.146. LRU 缓存机制146. LRU 缓存机制问题:运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。实现 LRUCache 类:1.LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存2.int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。3.void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在原创 2021-04-12 17:05:25 · 336 阅读 · 0 评论 -
力扣刷题——零钱兑换1+2(动态规划)
0.上一个动规专题力扣4—动态规划1.零钱兑换(动态规划)322. 零钱兑换给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。你可以认为每种硬币的数量是无限的。1.解题思路(动态规划)1.建立动态数组 int[] dp = new int[amount+1],解释:0元~amount元共amount+1个状态;2.dp[i]表示,凑够i元需要的最少的硬币数;3.假设co原创 2021-04-11 17:17:09 · 224 阅读 · 0 评论 -
力扣刷题—字符串
1.14. 最长公共前缀最长公共前缀编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。1.解题思路(横向对比)1.新建变量comm储存当前的公共前缀,初始化为字符串数组的元素;2.对每一个字符串s进行遍历,comm与s的字符从前向后进行比较,遇到不同的时跳出;3.当公共部分长度为0时,跳出。class Solution { public String longestCommonPrefix(String[] strs) {原创 2021-04-06 23:27:32 · 225 阅读 · 0 评论 -
力扣—数组(排序、快慢指针、异或位运算)
1. 删除有序数组中的重复项26. 删除有序数组中的重复项给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。1.解题思路(快慢指针)1.当slow与fast下标,对应的数不同时,slow++,然后把fast下标对应的值赋给slow下标;2.slow下标走过的每一个数都是不同的,因为一旦相同,slow就停止不动,等到出现与f原创 2021-04-05 21:15:44 · 205 阅读 · 0 评论 -
力扣—链表题目
1. 反转链表剑指 Offer 24. 反转链表定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。1.解题思路(迭代方法)1.节点 cur、next,每次用temp先存储next.next节点;2.然后改变next.next=cur,改变指针指向,由后向前;3.cur=next,节点cur向后滑动;4.next=temp,节点next滑动至temp处。注意:进入while循环前,cur.next=null; 这一步不能忘!时间复杂度:n;空间复杂度:1.原创 2021-04-02 23:11:54 · 157 阅读 · 0 评论 -
力扣刷题——排序题目
1.选择排序从数组中选择最小的元素,将他与第一个元素交换,再从剩下的元素中选择第二小的元素,将他与第二个元素交换, 依此类推。复杂度:要经过: n²/2 次比较 n次交换时间复杂度: O(N²)空间复杂度:O(1)稳定性不好class Solution1 { public int[] sortArray(int[] nums) { for (int i = 0; i < nums.length; i++) { int mi原创 2021-03-31 12:17:03 · 913 阅读 · 0 评论 -
力扣刷题—股票买卖集合
labuladong大神的详细讲解——股票问题1.穷举框架采用穷举思想,就是把所有的状态都列举出来,看看总共有几种状态,再找出每个状态对应的选择。我们要穷举所有的状态,穷举的目的是根据对应的选择更新更新状态...原创 2021-03-30 21:20:11 · 230 阅读 · 0 评论 -
力扣4—动态规划
1.动态规划的框架labuladong关于动态规划的透彻分析1.什么是动态规划?1.动态规划一般是求最值,比如最长递增子序列,最大股票收益……2.动态规划的核心是穷举。穷举完,然后求最值;3.它存在“重叠子问题”,如果单纯暴力穷举,时间复杂度太高,需要建立备忘录(DP table)来优化穷举过程,避免不必要的计算;4.动态规划必定存在最优子结构,才能通过子问题的最值得到原问题的最值;5.找到正确的状态转移方程,才能正确的穷举;2.动态规划的框架1.明确【状态】;2.定义dp数组,函原创 2021-03-28 21:05:06 · 306 阅读 · 0 评论