
letcode刷题
letcode刷题
HardyDragon_CC
谦虚使人进步
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
leetcode hot100 easy
leetcode hot100 easy原创 2023-02-02 17:49:45 · 419 阅读 · 0 评论 -
1143.最长公共子序列
1143.最长公共子序列思路dp:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]class Solution { public int longestCommonSubsequence(String text1, String text2) { int size1 = text1.length(); int size2 = text2.length(); int[原创 2021-10-24 20:39:46 · 165 阅读 · 1 评论 -
718. 最长重复子数组
718. 最长重复子数组思路求连续子序列、子数组,dp适合。dp[i][j] 以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。递推从1开始,利用初始值dp[0][0]class Solution { public int findLength(int[] nums1, int[] nums2) { // 数组初始化大小需要注意多一行一列 int[][] dp = new int[nums1.length +原创 2021-10-23 09:06:40 · 130 阅读 · 0 评论 -
674. 最长连续递增序列
674. 最长连续递增序列思路dp,以下标 i 为结尾的数组的连续递增的子序列长度为dp[i]。默认所有连续长度为 1递推公式:当 i + 1 项大于 i 项时,说明后面 i + 1 可连续;即 dp[i+1] = d[i] + 1;class Solution { public int findLengthOfLCIS(int[] nums) { int size = nums.length; int[] dp = new int[size];原创 2021-10-22 08:53:15 · 125 阅读 · 0 评论 -
300.最长递增子序列
300.最长递增子序列思路dp,表示i之前包括i的最长上升子序列;Arrays.fill(dp, 1); 初始化所有值为1,因为单个子序列长度为 1;递增子序列的新加入元素必须比前面的元素都大class Solution { public int lengthOfLIS(int[] nums) { int size = nums.length; if(size < 2) return size; int[] dp = new in原创 2021-10-21 09:15:06 · 141 阅读 · 0 评论 -
714.买卖股票的最佳时机含手续费
714.买卖股票的最佳时机含手续费思路在卖出比较的时候减去手续费即可class Solution { public int maxProfit(int[] prices, int fee) { int size = prices.length; if(size == 0) return 0; // 0 持有股票, 1 无股票 int[][] dp = new int[size][2]; dp[0][0] =原创 2021-10-20 08:30:12 · 97 阅读 · 0 评论 -
309.最佳买卖股票时机含冷冻期
309.最佳买卖股票时机含冷冻期思路四种dp 状态:买入,卖出、今日卖出、冷冻初始化只需要将买入的设置为价格负数,其他三个卖出利润都是0class Solution { public int maxProfit(int[] prices) { int size = prices.length; if(size == 0) return 0; // 0 买入 1 卖出状态 2 今天卖出 3 冷冻期 int[][] dp =原创 2021-10-19 09:27:54 · 105 阅读 · 0 评论 -
188.买卖股票的最佳时机IV
188.买卖股票的最佳时机IV思路dp 二维数组的含义是 第 i 天第 k 次交易状态(买入卖出)的利润;初始化dp数组时,所有的买入都是 -price[0];所有的卖出都是 0;递推的是第 k 次买入和卖出的利润;最后要返回的最后一次卖出的利润,所以递推时 要使得 j + 2 = 2 * k ,即遍历条件为 for(int j = 0;j <= 2 * k - 2;j += 2);最后 return dp[size - 1][2 * k];class Solution {原创 2021-10-18 10:51:43 · 117 阅读 · 0 评论 -
123.买卖股票的最佳时机III
123.买卖股票的最佳时机III思路dp,最多只能买卖两次,每天有五种状态,其中四种需要讨论。dp[i][] 每天的各个状态的利润。卖出的利润一定比买入的利润大dp 初始化时,看作第一天可以多次买入卖出。例如第一天的第二次买入初始化可以是第一次买入卖出后再买入,因为第一天买入卖出价格一样所以利润为0,再买入就是 -prices[0]class Solution { public int maxProfit(int[] prices) { if(prices.lengt原创 2021-10-17 09:46:31 · 111 阅读 · 0 评论 -
122.买卖股票的最佳时机II
122.买卖股票的最佳时机II思路可以多次买卖,计算持有时将上次的利润加上。可以利用滚动数组节约空间返回滚动数组最后的下标需要用 size 确定class Solution { public int maxProfit(int[] prices) { if(prices.length == 1) return 0; int size = prices.length; int[][] dp = new int[size][2];原创 2021-10-16 10:02:26 · 104 阅读 · 0 评论 -
121. 买卖股票的最佳时机
121. 买卖股票的最佳时机思路dp是个二维数组,表示第i天持有和不持有的最高收益。数组初始化,对于第一天就入股的资产为 -price[0],不买的为0;后面递推公式,对于持有和不持有的分别两种情况;持有的递推,继续持有,其收益和昨天持有的一样。今天刚持有,收益为 -price[i]不持有的递推,继续不持有,收益和昨天一样,今天刚卖出,今天的收益为昨天持有的收益加上今天卖出的价格 ,即 dp[i-1][0] + prices[i]class Solution { public int原创 2021-10-15 09:50:20 · 106 阅读 · 0 评论 -
337.打家劫舍 III
337.打家劫舍 III思路题目要求不能同时偷父结点和其孩子结点。要么偷父结点,要么偷其两个孩子结点。这里可以使用一个长度为2的状态数组,记录当前节点偷与不偷所得到的的最大金钱。关于树的的遍历这里使用后序遍历,左右根。最后返回的就是根节点的dp数组中的偷与不偷当前结点的金额的最大值。class Solution { public int rob(TreeNode root) { int[] dp = robrec(root); return Math.原创 2021-10-14 09:47:09 · 98 阅读 · 0 评论 -
213.打家劫舍II
213.打家劫舍II思路考虑不包含头元素和不包含尾元素的两种情况,取最大值;利用函数求区间的最大金额class Solution { public int rob(int[] nums) { if(nums.length == 1) return nums[0]; if(nums.length == 2) return Math.max(nums[0],nums[1]); // 不包含尾元素的区间最高金额 int r1 =原创 2021-10-13 10:46:26 · 100 阅读 · 0 评论 -
198.打家劫舍
198.打家劫舍思路dp的含义,至下标为 i 的房屋能得到的最大价值由于题目限制,dp[ i ] 不能考虑其前一个 dp[ i - 1],所以对于 dp[ i ] 要考虑 dp[ i - 2];class Solution { public int rob(int[] nums) { if(nums.length == 1) return nums[0]; int size = nums.length; int[] dp = new in原创 2021-10-13 08:41:03 · 90 阅读 · 0 评论 -
494. 目标和
494. 目标和思路该表达式由 加法和 x 与 减法和 sum-x 构成;题目求 x - (sum - x) = target,x = (target + sum) / 2;将 加法和 x 作为背包重量,转换为01背包问题有两种情况无解,1. (target + sum) 为奇数不能整除,得不到 x。例如 【1,1】的 sum = 2,target = 1; 1+2为奇数,无解。2. 绝对值 target 大于 sum,例如 target = 10,sum = 2;dp[0] = 1;求原创 2021-10-10 09:39:09 · 97 阅读 · 0 评论 -
1049 最后一块石头的重量 II
最后一块石头的重量 II思路尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。所以背包的最大容量为 sum / 2;求出背包最大容量的重量后,用 sum 消去两堆石头得到剩下的石头重量。class Solution { public int lastStoneWeightII(int[] stones) { int sum = 0; for(int num: stones) sum += num; int原创 2021-10-09 08:10:04 · 104 阅读 · 0 评论 -
416 分割等和子集
https://leetcode-cn.com/problems/partition-equal-subset-sum/思路:利用01背包动规解决;dp 数组的含义就是: 背包容量 j 能装的最大容量为 dp[ j ];背包重量就是数组和的一半;dp 递推公式是: dp[ j ] = max(dp[ j ], dp[ j - nums[ i ] ] + nums[ i ]); 考虑放不放当前的物品 i ,取价值最高的。其中 nums 的元素其价值和重量是等价的代码使用了一维滚动数组,其遍历顺序原创 2021-10-08 09:15:36 · 108 阅读 · 0 评论 -
56 合并区间
56 合并区间class Solution { public int[][] merge(int[][] intervals) { List<int[]> res = new LinkedList<>(); Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0])); int start = intervals[0][0]; fo原创 2021-09-21 18:22:08 · 138 阅读 · 0 评论 -
力扣刷题笔记--304 二维区域和检索 - 矩阵不可变 前缀和
304 二维区域和检索 - 矩阵不可变作者:AC_OIer链接:https://leetcode-cn.com/problems/range-sum-query-2d-immutable/solution/xia-ci-ru-he-zai-30-miao-nei-zuo-chu-lai-ptlo/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。思路:二维前缀和解决的是二维矩阵中的矩形区域求和问题。二维前缀和数组中的每一个格子记录的是「以当原创 2021-08-05 11:31:01 · 267 阅读 · 0 评论 -
BFS/DFS处理二维矩阵抽象问题例题
这是自己搜集的有关bfs和dfs关于二维01数组的例题BFS烂橘子01矩阵图像渲染DFS岛屿数量岛屿最大面积BFS烂橘子这里队列存储数组下标的方式和其他的不同class Solution { int[] dr = new int[]{-1, 0, 1, 0}; int[] dc = new int[]{0, -1, 0, 1}; public int orangesRotting(int[][] grid) { int R = grid.length, C原创 2021-07-15 21:12:12 · 219 阅读 · 0 评论 -
java--快速排序
快速排序什么是快速排序?双边循环法demo调试单边循环法什么是快速排序?排序动画演示网站属于交换排序的一种,利用了分治的思想,将序列根据 pivot (中间值) 划分为两个序列,在 pivot 左边的元素全部都比 pivot 值小,在右边的比 pivot 大,对子序列递归操作。双边循环法demo递归,利用辅助函数确定 pivot 的索引并排序。package sort;/** * @Description: TODO * @author: HardyDragon * @date: 20原创 2021-07-07 15:44:48 · 111 阅读 · 0 评论 -
java实现冒泡排序
java实现冒泡排序前言BubbleSort 冒泡排序调试使用交换 flag 优化调试总结前言C语言实现冒泡排序 在主函数调用之前使用C实现过冒泡,但是不够精炼,描述不够简洁,便使用java来重新输出一下。BubbleSort 冒泡排序排序动画演示网站(建议收藏)冒泡排序是将一个无序的序列(例如数组),从头开始两两比较交换直到有序的过程,每轮两两交换可以让后面部分元素有序。例如,{3,9,6} 当交换比较到 {3,6,9} 后两个元素(数组大小 3 - 1 = 2 )有序时,整体有序。下原创 2021-07-06 11:07:11 · 149 阅读 · 0 评论 -
C实现希尔排序 主函数调用
> **注意:**> 希尔排序是直接插入排序的优化,都属于插入排序,希尔排序思路是先对一定间隔的序列进行直接插入排序,不断缩小间隔至1,即为直接插入排序,但是通过一定间隔的方式可以减少直接插入排序的交换次数,希尔排序是先大致有序,最后再直接插入排序。>平均时间复杂度:O(N^1.3)原创 2020-11-20 20:18:56 · 647 阅读 · 0 评论 -
C数组实现二分查找(又名折半查找) 主函数调用
>注意:>使用二分查找必须是 **有序** 的对象,即先排序后二分查找。>平均时间复杂度: **O(log2n)** >思路:记录一个表的low、high、mid 查找 key 如果 key 大于 mid 下标的值就表明要查找的key 可能在 mid 的右边,将 low 变为 mid + 1;如果 key 小于 mid 下标的值 表明要查找的值可能在 mid 的左边,将 high 变为 mid - 1;当 low 大于 high 时跳出查找。原创 2020-11-26 17:37:18 · 525 阅读 · 0 评论 -
C递归实现归并排序 主函数调用
C递归实现归并排序 主函数调用归并排序有递归实现和非递归实现,实际中使用非递归实现较多,因为其性能相对递归实现来说更好,这里给出的递归实现归并排序:可视化排序算法:https://visualgo.net/zh/sorting先上代码:#include <stdio.h>#include <stdlib.h>void msort(int a[], int s, int e);void merge_sort(int a[], int length);void merg原创 2020-11-23 09:50:10 · 526 阅读 · 0 评论 -
C链表实现基数排序 主函数调用
> **注意:**> 基数排序可以有低位/高位作为关键点,一般使用低位,高位的代码更加复杂。其平均时间复杂度为O(n*k)每次都要安利的排序可视化网站:[https://visualgo.net/en/sorting](https://visualgo.net/en/sorting)先上代码,由于基数排序一般使用链表来实现,所以需要提前使用结构体定义原创 2020-11-25 12:20:05 · 342 阅读 · 0 评论 -
C直接插入排序 主函数调用
> **伪代码**> 假设第一个元素认为已排序,> 遍历剩余未排序的元素> 提取第一个未排序的元素作为临时变量temp> 遍历已排序的元素,将其和temp做比较,如果temp小于排序的元素,就将排序的元素右移给temp空出位置。> 当遇到temp大于已排序的元素时,插入到当前位置。其中内循环需要遍历已排序的元素,从后往前遍历,找到比temp小的元素,然后插入到前面,其中需要不断将比temp大的元素往右移,之前temp的位置会被最后一个已排序的元素所替代。原创 2020-11-19 22:05:39 · 1140 阅读 · 0 评论 -
C 实现选择排序 在主函数中调用
C 实现选择排序 在主函数中调用先上代码#include <stdio.h>void Printarr(int arr[], int length); // print arraryvoid SelectSort(int arr[], int length); // sortint main(int argc, char const *argv[]){ int arr[] = {45, 29, 40, 25, 98, 77, 46, 20, 21, 21}; in原创 2020-11-18 15:11:09 · 1702 阅读 · 0 评论 -
C递归实现快速排序 主函数调用
> **注意:**> 快速排序的思路是 对一个子表取第一个作为初始 **支点** ,经过 **partition** 函数的排序后返回新的支点下标,排序后该子表的支点放在中间的合适位置(即支点左边的值小于支点,右边的值大于支点)。然后对左右子表递归调用 **partition** 函数进行排序,直到每一个子表长度为1时停止(这点和归并排序递归调用很像),排序便完成了。>快速排序的平均时间复杂度 : **O (nlogn)** , 体现了递归,分而治之的思想。原创 2020-11-24 17:05:00 · 848 阅读 · 0 评论 -
C语言实现冒泡排序 在主函数调用
C语言实现冒泡排序 在主函数调用实现冒泡排序的方式很多种,还有各种优化版本,冒泡的方向不同,这里是以从小到大排序为例,对C语言的数组进行排序,有将数组换做指针的写法,但是冒泡排序的本质都是相同的,其时间复杂度都是O(N方),因为其最重要的就是双重循环比较交换。原创 2020-11-17 15:58:28 · 5756 阅读 · 0 评论 -
二分查找笔记(1)
二分查找什么是二分查找?二分查找模板一什么是二分查找?在最简单的形式中,二分查找对具有指定左索引和右索引的连续序列进行操作。这就是所谓的查找空间。二分查找维护查找空间的左、右和中间指示符,并比较查找目标或将查找条件应用于集合的中间值;如果条件不满足或值不相等,则清除目标不可能存在的那一半,并在剩下的一半上继续查找,直到成功为止。如果查找以空的一半结束,则无法满足条件,并且无法找到目标。作者:力扣 (LeetCode)链接:https://leetcode-cn.com/leetbook/read/原创 2021-07-05 10:32:20 · 133 阅读 · 0 评论 -
刷题笔记(21)--平衡二叉树
平衡二叉树技巧:递归返回值可以表示两种状态。补充:递归计算二叉树高度平衡二叉树技巧:递归返回值可以表示两种状态。class Solution { // 递归辅助函数,其返回值有两种,如果树平衡返回的是树的深度(左右子树取最大值);如果不平衡,返回 -1; private int depthTree(TreeNode root){ if(root == null) return 0; int ld = depthTree(root.left);原创 2021-06-29 10:46:42 · 92 阅读 · 0 评论 -
刷题笔记(20)--对称的二叉树
对称的二叉树递归,辅助递归函数check() ,传入两个参数一个原始结点,另一个镜像结点。最小问题是镜像的判断,结点的左子节点 == 镜像过后的左子节点(即原来的右子结点),同理右子结点。。。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) {原创 2021-06-28 09:31:00 · 84 阅读 · 0 评论 -
刷题笔记(19)--把数组排成最小的数
把数组排成最小的数根据整形数组生成字符串数组对字符串数组使用内置函数 sort(排序数组,比较器) 进行排序,排序规则是如果 s1+ s2 的字典序大于 s2 + s1,说明 s1要放在 s2 后面,反之。compareTo 结果大于0,说明要排序,将两个参数交换位置。最后拼接排序后的字符数组返回字符串即可class Solution { public String minNumber(int[] nums) { String[] strs = new String原创 2021-06-27 10:02:37 · 96 阅读 · 0 评论 -
刷题笔记(18)--剪绳子II(贪心)
剪绳子II这题和 前面的剪绳子n的取值范围不同,涉及到了大数会越界的问题,需要每次都对其取余。n=2时,特殊解为11=1;n=3时,特殊解为12=2;n=4,2*2=4;n>4时,最优解应该是包含尽可能多的长度为3的子绳。例如n=6,最优解为33,而不是22*2;使用 long 存储结果还不够,还需要做到每次的中间结果都取余。class Solution { public int cuttingRope(int n) { // 对于 2 3 返回 1 和 2是特原创 2021-06-26 08:48:51 · 117 阅读 · 0 评论 -
刷题笔记(17)--整数拆分/剪绳子(动态规划)
剪绳子相同题目:整数拆分使用动态规划解题:使用dp数组存储直到 n 的最大乘积。dp[n] 就是要返回结果dp[0] = dp[1] = 0 : 这意味dp数组从索引 2 开始递推dp[i] 存放 i 的最大乘积dp[i] 有两种情况:假设 j 是其中一段的长度,另一个乘积有两种可能只有两段 j、i-j ; 其乘积是 j * (i-j) :题目要求 m>1,所以至少两个,即 j 不能等于 0;或者 j 和 dp[i-j] 多段构成,dp[i-j] 是之前存储的 i-j 的最大乘原创 2021-06-25 08:50:35 · 107 阅读 · 0 评论 -
刷题笔记(16)--机器人的运动范围(BFS搜索)
机器人的运动范围(BFS搜索)DFS利用递归栈实现,BFS使用队列实现。BFS可以套模板,这里需要自己实现的就是求数位之和函数,利用整除和取余运算操作。class Solution { public int movingCount(int m, int n, int k) { if(k == 0){ return 1; } Queue<int[]> queue = new LinkedList<>原创 2021-06-24 09:36:41 · 127 阅读 · 0 评论 -
刷题笔记(15)--矩阵中的路径
矩阵中的路径矩阵搜索类题目,可以使用dfs递归查找;dfs函数作用:返回在矩阵board中,是否存在一个字符串数组word,从第i行j列开始逐个匹配word的每一个元素,若存在返回true,反之返回false;结束条件:行列超出界限,改元素之前访问过返回值:对元素上下左右进行递归查找,取其或的布尔结果;小操作:在子问题的操作上还要考虑一点,我们使用直接修改值的方式来表示矩阵元素已经被访问过,之后递归如果不想受到影响,还需要在得到res结果后复原该位置的元素值,为了下次递归能够访问原创 2021-06-23 09:43:35 · 132 阅读 · 0 评论 -
刷题笔记(14)--旋转数组的最小数字
旋转数组的最小数字class Solution { public int minArray(int[] numbers) { int left = 0; int right = numbers.length - 1; // 利用二分查找的思想 使得left 和 right 落在最中间的两个位置,取其中最小的值 while(right - left > 1){ // 对左右去重原创 2021-06-22 09:23:40 · 89 阅读 · 0 评论 -
刷题笔记(13)
斐波那契数列直接使用递归会超时,因为包含了太多的重复计算,为了减少重复计算,使用哈希表存储之前计算的结果,再次遇到直接查表就可以了。需要注意的是判断map中是否存在某一键返回布尔的方法是 containsKey() ;class Solution { Map<Integer,Integer> map = new HashMap<>(); public int fib(int n) { if(n<2){ return原创 2021-06-21 08:47:49 · 82 阅读 · 0 评论