自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(150)
  • 收藏
  • 关注

原创 LeetCode322.零钱兑换(记忆化搜索,动态规划)

LeetCode322.零钱兑换解法记忆化搜索动态规划记忆化搜索/*返回可以凑成总金额的最少的硬币个数*/func coinChange(coins []int, amount int) int { var f = make([]int, amount) /* 记忆化搜索,自顶向下, f[i]表示兑换i+1元需要的最少硬币数 */ var searchChange func(coins []int, amount int) int searchChange = func(coin

2021-10-11 11:17:52 233

原创 LeetCode312. 戳气球 (分治,记忆化搜索,动态规划)

LeetCode312. 戳气球 解题思路记忆化搜索动态规划解题思路官方题解参考题解核心思想:由于戳气球的操作会导致两个气球从不相邻变成相邻,使得后续操作难以处理。于是我们倒过来看这些操作,将全过程看成每次添加一个气球。solve(i, j)表示 开区间(i, j) 所能获得的最大硬币数。当开区间只包含一个气球mid时,solve(i, j) = val[i] * val[mid] * val[j]记忆化搜索自顶向下分治+递归+记忆/*解法一: 记忆化搜索 由于戳气球的操作

2021-10-10 16:34:51 241

原创 LeetCode309. 最佳买卖股票时机含冷冻期(动态规划)

LeetCode309. 最佳买卖股票时机含冷冻期 /*计算最大利润,不能同时参与多笔交易,卖出后无法在第二天买入(冷冻期为1天)动态规划 每一天会有三种不同的状态: 1. 目前持有一支股票,对应的[累计最大收益]为dp[i][0] 2. 目前不持有任何股票,且处于冷冻期中,对应的[累计最大收益]为dp[i][1] 3. 目前不持有任何股票,且不处于冷冻期中,对应的[累计最大收益]为dp[i][2] 注意:这里处于冷冻期是指第二天即i+1不处于冷冻期 状态转移: 1. 目

2021-10-10 13:36:22 174

原创 LeetCode301 删除无效的括号(深度遍历+剪枝)

LeetCode301. 删除无效的括号/*一次遍历获取需要删除的左括号的个数和右括号的个数,遇到右括号: 如果左括号个数不为0,则左括号个数--; 如果左括号个数为0,则右括号个数++;遇到左括号: 左括号个数++这样子一次遍历后,左括号个数和右括号个数即为各自需要删除的个数。然后通过深度遍历+剪枝尝试删除,使用hash表去重。需要严格保证 [已经遍历到的左括号的数量] 大于 [已经遍历到的右括号的数量] 的时候,才可以继续添加 [右括号],并且只有当该删除的括号都删除完全即左括号

2021-10-09 19:35:28 125

原创 Leetcode1117. H2O 生成 (多线程编程)

原题链接H2O生成Semaphore 信号量Semaphore 信号量 + CyclicBarrier 同步屏障Semaphore 信号量每生成两个氢原子,再去生成一个氧原子class H2O { private Semaphore s; private Semaphore o; public H2O() { s = new Semaphore(0); o = new Semaphore(2); } public void

2021-06-28 15:09:09 184

原创 KMP算法

KMP模式匹配算法推导代码例题推导KMP是一种字符串模式匹配的改进算法。假定模式串为B,主串为A,当B[j]和A[i]不匹配时,i不会回退,j并不会从位置0开始重新匹配,而是回退到合适的位置。那么,KMP算法首先应该解决的就是如何找到合适的回退位置。代码显然时间复杂度为O(n + m), 空间复杂度为O(m),n是文本串的长度,m是模板串的长度 /** * kmp算法 * * 计算模板串S在文本串T中出现了多少次 * @param S stri

2021-06-12 16:13:02 76

原创 旋转数组的最小数字 (二分法)

旋转数组的最小数字NC71直接上代码和注释 /** * 二分法 * 如果二分之后能够明确目标值在二分的哪一侧, * 即可使用二分法 * * 二分得到一个mid,arr[mid]要和一个compVal比较以判断 * 目标值的位置, * 若 compVal为arr[right], * 1. arr[mid] > compVal, 最小值一定是在mid的右侧,

2021-06-08 11:06:36 99

原创 牛客NC125 未排序数组中累加和为给定值的最长子数组长度(动态规划、哈希法)

牛客NC125直接上代码和注释目录动态规划哈希法类似的题目动态规划时间复杂度O(n ^ 2),空间复杂度O(1) /** * 动态规划 * 状态dp[i][j],子数组[i-j]的和 * * 可以进行空间压缩 * max length of the subarray sum = k * @param arr int整型一维数组 the array * @param k int整型 target *

2021-06-07 17:08:52 159

原创 矩阵最长递增路径 (记忆化的递归搜索,动态规划)

牛客NC138 矩阵最长递增路径leetcode329 矩阵中的最长递增路径记忆化的深度优先遍历每个点的最长递增路径是确定,因此我们可以记录每个点的最长递增路径的长度,下一次访问到该点时就直接返回路径长度即可。会不会出现路径重复的情况(如下图的情况)呢?很明显是不会的,因为路径是递增的,这种情况会破坏路径的递增关系。 private int[][] dirs = new int[][]{{1, 0}, {0, -1}, {-1, 0}, {0, 1}}; private in

2021-06-02 13:40:47 212

原创 股票交易的最大收益(二)(两次交易,动态规划)

牛客NC135股票交易的最大收益(二)import java.util.*;public class Solution { /** * 动态规划, * dp[i][0],直到第i天第一次买入的最大收益 * dp[i][1],直到第i天第一次卖出的最大收益 * dp[i][2],直到第i天第二次买入的最大收益 * dp[i][3],直到第i天第二次卖出的最大收益 * 买入就减收益,卖出

2021-06-02 11:11:41 871

原创 牛客NC126 换钱的最小货币数(动态规划)

原题链接 动态规划递归 时间复杂度过高动态规划时间复杂度为O(n * aim), 空间复杂度为O(aim),n是arr数组的长度 /** * 最少货币数 * 动态规划: * 状态: dp[i],凑成i元需要的货币数 * * @param arr int整型一维数组 the array * @param aim int整型 the target * @return int整型 */

2021-05-18 12:40:55 195

原创 经典算法题:约瑟夫环

约瑟夫环问题问题定义解法1. 模拟链表2. 数学方法(时间复杂度较低)例题问题定义0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。解法1. 模拟链表该方法时间复杂度为O(n * m)/** * @author 49367 * @date 20

2021-05-14 15:27:52 264

原创 树的直径(最长路径)

无向连通树无向连通树即其直径定义如何求直径深度优先遍历证明:树形DP例题无向连通树即其直径定义有一无向连通树,该树的直径就是树上最远两点的距离。无向连通树: 从一个顶点出发能够到达任意一个顶点,且有n个顶点,n-1条边,没有环。如何求直径深度优先遍历深度优先遍历。先从任意一个顶点 u 出发寻找以其为起点的最长路径,再从终点出发寻找以该终点 s 为起点的最长路径。以该终点为起点的最长路径即为树的直径。证明:如果u是树直径(最长路径) s -> t上的一点,那么以u为起点寻找最长路径,终

2021-05-12 20:56:51 443 1

原创 LFU缓存

LFULFU算法实现堆 + 版本号双哈希表+LinkedList双哈希表+自定义双向链表 (时间复杂度最低)LFU算法最近最少次数访问,缓存满的时候,优先淘汰掉最少访问的数据,若最少访问次数的数据有多个,淘汰掉访问时间与现在相隔最远的数据。实现堆 + 版本号由于涉及到构建堆,所有操作的时间复杂度均为O(logN)public class LFU{ class Node{ int key; int val; int count;

2021-04-30 17:41:03 269 1

原创 牛客NC6 二叉树的最大路径和(二叉树的遍历,递归,动态规划)

原题链接/** * @author 49367 * @date 2021/4/28 10:54 */public class MaxPathSumNC6 { private int maxSum = Integer.MIN_VALUE; /** * 获取树的最大路径,开始结点和结束结点都可以是任意结点 * @param root TreeNode类 * @return int整型 */ public int maxPathSum (

2021-04-28 13:45:24 189

原创 牛客NC30 数组中未出现的最小正整数

原题链接解题思路:使用堆排序,构造小顶堆。时间复杂度O(nlogn),空间复杂度O(1)使用HashMap,时间复杂度O(n),空间复杂度O(n)原地哈希,时间复杂度O(n), 空间复杂度O(1)具体实现: /** * 原地哈希算法 (哈希算法的改良版) * 给定一个数组arr,数组长度为len,未出现的最小正整数一定不会超过len + 1, * 即 [1, len] 这个区间的数都出现了,那么未出现的最小正整数就是len + 1,

2021-04-25 12:25:02 180

原创 牛客 NC60 判断该二叉树是否为搜索二叉树和完全二叉树 (二叉树,层序遍历,中序遍历)

原题链接判断搜索二叉树可以用中序遍历或者递归判断搜索二叉树的方法用递归 /** * * @param root TreeNode类 the root * @return bool布尔型一维数组 */ public boolean[] judgeIt (TreeNode root) { // write code here boolean[] res = new boolean[]{false, false};

2021-04-19 18:33:56 92

原创 牛客NC92 输出两个字符串的最长公共子序列(动态规划)

原题链接public class Solution{ /** * 动态规划 * 状态:dp[i][j] 表示s1前i个字符和s2前j个字符的最长公共子序列的长度 * * 状态转移方程: * 若s1[i] = s2[j], dp[i + 1][j + 1] = dp[i][j] + 1 * 为什么不考虑dp[i + 1][j]或dp[i][j + 1]? *

2021-04-18 14:20:26 458

原创 牛客NC35 最小编辑代价 (动态规划,压缩空间的动态规划)

原题链接理解动态规划后,压缩空间是一大难点,需要找出遍历过程中需要用到的状态和不需要用到的状态,去掉不需要用到的状态,存储需要用到的状态。import java.util.*;public class Solution { /** * 动态规划 * 状态:dp[i + 1][j + 1],str1[0-i]编辑成str2[0-j]的最小cost * * min edit cost * @param str1 string字符串 t

2021-04-14 23:01:30 226

原创 实现简单计算器 (逆波兰表达式)

牛客NC137 表达式求值(原题链接)逆波兰表达式相关博客将一个大问题分解成一个个小问题来求解,就不会被难题的复杂度给吓倒。代码实现:核心函数: /** * 写一个整数计算器,支持加减乘三种运算和括号 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve (String s) { // write code here

2021-04-13 13:08:24 112

原创 牛客NC59 矩阵的最小路径和 (动态规划,压缩空间的动态规划)

原题链接解题方法暴力递归(时间复杂度过高)动态规划压缩空间的动态规划(可以降低空间复杂度)暴力递归(时间复杂度过高)每个位置都尝试向右走和向左走,时间复杂度较高,为 O(2 ^ (n * m))public class Solution{ private int minPathSum; /** * @param matrix int整型二维数组 the matrix * @return int整型 */ public int minPathSu

2021-04-12 22:20:35 120

原创 牛客NC73 数组中出现次数超过一半的数字 (候选法、摩尔投票算法)

牛客网原题链接leetcode剑指Offer39如何理解摩尔投票算法核心思路:对拼消耗玩一个诸侯争霸的游戏,假设你方人口超过总人口一半以上,并且能保证每个人口出去干仗都能一对一同归于尽。最后还有人活下来的国家就是胜利。那就大混战呗,最差所有人都联合起来对付你,或者其他国家也会相互攻击),但是只要你们不要内斗,最后肯定你赢。最后能剩下的必定是自己人。 /** * 找出数组中出现次数超过数组长度len的一半的数,若没有则返回0 * 最佳解法: * 候选法

2021-04-12 20:30:22 142

原创 牛客NC62 判断是不是平衡二叉树 (二叉平衡树)

原题链接这虽然是一道简单题,但是要找到最佳的解法还是比较困难的解题方法最直接的思路使用Map结构存储高度信息后序遍历自底向上同时返回高度信息我的解法 (自定义高度类存储高度信息)他人的解法(不需要自定义类)最直接的思路这道题,最直接的思路就是从上到下,判断每一个结点的左子树和右子树的高度差是否小于或等于1,所有结点都满足平衡二叉树的条件才能返回true。也可以根据后序遍历,从下往上判断。但是,这个解法有个问题,就是我们在求位于上方的结点的最大高度的时候,其实已经把下方的结点的最大高度也给求出来了,

2021-04-12 17:15:52 145

原创 牛客NC136 根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图(二叉树,深度遍历)

原题链接绝大部分题解都是先重建二叉树,然后再对二叉树进行层序遍历输出它的右视图。其实,我们可以在重建二叉树的过程中,同时得到它的右视图。核心思路:二叉树的右视图是它由上到下每一层最靠右的结点的集合。代码如下:/** * @author 49367 * @date 2021/4/11 16:17 */public class Solution{ private HashMap<Integer, Integer> inRootMap; private List&lt

2021-04-11 16:56:55 272

原创 全排列算法

全排列的几种算法相关题目字典序算法回溯法(深度遍历 + 剪枝)结果不要求排序结果要求排序相关题目牛客NC121字符串的排列leetcode剑指 Offer 38. 字符串的排列字典序算法public class Solution{ char[] charArray; ArrayList<String> res; /** * 使用字典序算法 * @param str * @return */ public

2021-04-10 16:37:44 59

原创 线程(未完待续)

线程线程的实现方式用户线程内核线程用户线程和内核线程必然有联系多线程模型多对一模型优点缺点一对一模型优点缺点补充多对多模型轻量级进程线程的实现方式用户线程用户线程的管理无需内核的支持。内核线程内核线程由操作系统来直接支持与管理。内核线程从来不会访问属于用户态虚拟地址空间,这种线程只在内核虚拟地址空间范围活动。用户线程和内核线程必然有联系多线程模型多对一模型一个进程里的多个用户线程映射到一个内核线程。这种模型下,线程管理由用户空间的线程库来完成。优点可以在不支持线程的操作系统中实现。

2021-04-09 14:05:28 53

原创 剑指 Offer 59 - II. 队列的最大值 设计一个能够获得最大值的队列(队列)

原题链接相关题目,相关数据结构及其设计:设计一个能够获得最小值的栈能够获取最大值的队列class MaxQueue { private Deque<Integer> dataQueue; private Deque<Integer> maxQueue; public MaxQueue() { dataQueue = new LinkedList<>(); maxQueue = new LinkedList&l

2021-04-08 23:19:45 90

原创 牛客NC90 设计一个能够返回最小值的栈(栈)

原题链接/** * @author 49367 * @date 2021/4/8 20:58 */public class GetMinStackNC90 { /* 利用栈先进后出的特性。 */ private Deque<Integer> dataStack = new LinkedList<>(); private Deque<Integer> minStack = new LinkedList<>();

2021-04-08 23:04:34 71

原创 牛客NC32 求平方根(二分法,牛顿迭代法)

原题链接 二分法牛顿迭代法 [参考链接1](https://blog.csdn.net/u010947534/article/details/87874019) [参考链接2](https://blog.csdn.net/weixin_42109012/article/details/91359268)二分法任何有边界的有序数字的集合的查找操作都可以使用二分法。这道题一开始我们很容易想到从num = 1开始求,num 加 1 直到 x / num = num为止。由于我们是按升序取数字的,且当 x &

2021-04-08 20:56:42 166

原创 牛客NC48 在转动过的有序数组中寻找目标值(二分查找)

原题链接不知道未经过转动的原数组是升序排列还是降序排列的情况下,我们可以先按升序二分查找,再按降序二分查找。 /** * 二分查找 * 当前数组肯定是有两部分是有序的,所以取mid时, * 要么 [l, mid] 是有序的,要么 [mid + 1, r]是有序的 * * @param A int整型一维数组 * @param target int整型 * @return int整型 */ p

2021-04-07 17:22:15 113

原创 最小生成树

最小生成树定义MST性质普利姆算法定义n个结点通过(n - 1) 条边即可相连,每条边都有各自的权重(代价),最小生成树就是从大于或等于n - 1条边中找出能连接n个结点的代价和最小的(n - 1)条边。MST性质假设 N = (V, {E}) 是连通网,其中V是所有顶点的集合,E是所有边的集合。#求最小生成树普利姆算法...

2021-04-06 23:09:59 241

原创 牛客NC91 最长递增子序列(动态规划、贪心+二分查找)

原题链接 动态规划(时间复杂度 O(n^2))贪心 + 二分查找 (时间复杂度 O(nlogn))动态规划(时间复杂度 O(n^2)) /** * return the longest increasing subsequence * @param arr int整型一维数组 the array * @return int整型一维数组 */ /** * 动态规划 * 状态 dp[i][2], dp[i][0]是以 a

2021-04-06 20:40:28 487

原创 牛客NC17 最长回文子串(动态规划)

原题链接 中心扩散法动态规划中心扩散法 /** * 中心扩散法 * * @param A * @param n * @return */ public int getLongestPalindrome(String A, int n) { // write code here char[] chars = A.toCharArray(); if (chars.length ==

2021-04-05 15:42:27 193

原创 LeetCode1143. 最长公共子序列 (动态规划)

原题链接 /** * 动态规划 * 状态 dp[i][j] 表示 text1前i个字符 和 text2前j个字符 的最长公共子序列的长度 * * 状态转移方程 * if text1[i] == text2[j], dp[i + 1][j + 1] = dp[i][j] + 1; * if text1[i] != text2[j], dp[i + 1][j + 1] = Math.max

2021-03-30 22:32:12 52

原创 根据二叉树遍历结果构建二叉树

目录[LeetCode105. 从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)[LeetCode106. 从中序与后序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)[LeetCo

2021-03-30 20:26:17 218

原创 二叉树遍历

前序遍历中序遍历后序遍历class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null;}前序遍历 /** * 前序遍历 * @param temp */ private List<Integer> dlr(TreeNode root) { LinkedList<Integer> res = new Linked.

2021-03-29 17:36:31 41

原创 判断链表中是否有环 返回环的入口结点 (快慢指针)

set集合法 (时间复杂度O(n), 空间复杂度O(n))快慢指针法(时间复杂度O(n),空间复杂度O(1))逐个删除法 (时间复杂度O(n),空间复杂度O(1)) class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } }set集合法 (时间复杂度O(n), 空间复杂度O(.

2021-03-29 16:42:33 105

原创 java LRU缓存实现

LRU缓存实现LinkedHashMap源码剖析继承LinkedHashMapLinkedHashMap源码剖析继承LinkedHashMap可以通过继承 LinkedHashMap 实现 LRU 缓存结构。代码如下:public class LRUCache<K, V> extends LinkedHashMap<K, V> { private final int MAX_ENTRIES; public LRUCache (int maxEntries)

2021-03-29 15:03:13 102 1

原创 数独问题

假设输入为 0 的位置是要求填数的位置,每次填数的时候都通过深度遍历判断填的数能不能解决数独问题,不能就再填另一个可以填的数,再进行判断。import java.util.Scanner;/** * @author 49367 * @date 2021/3/26 11:07 */public class Sudoku { private static final int SIZE = 9; // 数独矩阵 private static char[][] map = n

2021-03-27 14:07:28 52

原创 Java Map 按值 (value) 排序

可以使用 LinkedHashMap 和 List,之所以使用 LinkedHashMap 是因为 LinkedHashMap 是有序的,这里的有序是指 LinkedHashMap 会维护 entry 插入的顺序。LinkedHashMap<String, Integer> map = new LinkedHashMap<>();/** * 在此处对LinkedHashMap进行赋值操作 */Set<Map.Entry<String, Integer>&g

2021-03-27 14:03:54 488

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除