自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(84)
  • 资源 (1)
  • 问答 (1)
  • 收藏
  • 关注

原创 题目 1568: 蓝桥杯算法提高VIP-身份证排序

排序 重写Comparator就行了 没什么特殊的public class C1568 { public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextInt(); ArrayList<String> list = new ArrayList(); for (int i = 0;

2022-03-13 10:25:50 136

原创 题目 1975: 蓝桥杯算法提高VIP-扑克排序

package LanQiao.C_Web.C_1975;import java.util.ArrayList;import java.util.Comparator;import java.util.Scanner;/** * @author Huiex on 2022/3/12 */public class C1975 { public static void main(String[] args) { Scanner input = new Scanner(S

2022-03-12 21:06:01 155

原创 题目 1917: 蓝桥杯算法提高VIP-快乐司机

排序 实现compare方法即可package LanQiao.C_Web.C_1917;import java.util.ArrayList;import java.util.Comparator;import java.util.Scanner;/** * @author Huiex on 2022/3/12 */public class C1917 { public static void main(String[] args) { /** 输入*/

2022-03-12 21:04:17 173

原创 剑指 Offer 35. 复杂链表的复制

主要思路是:以为题目的要求返回的链表和给的链表位置不一样,所以要新建结点将新建结点和原结点放入Map中,key为原结点,value为新建结点然后通过在map中取出原结点,得到新节点,让新节点next指向 map中原结点的next对应新节点连接random也同理public class Offer35 { /** 题目的要求返回的链表和给的链表位置不一样,所以要新建结点*/ public Node copyRandomList(Node head) { if (hea.

2021-12-08 18:24:12 235

原创 剑指 Offer 59 - II. 队列的最大值

参考:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/solution/ru-he-jie-jue-o1-fu-za-du-de-api-she-ji-ti-by-z1m/主要思路就是 创建两个队列,一个是先进先出队列,一个是双向队列普通队里用来执行pop 和push双向队列用来执行最大值的存放 如果加入的数值大于双向队列的最后元素,就将该元素从双向队列的从末尾弹出,直到双向队列的末尾元素大于该数值,就将数值从后面放入双向队列

2021-12-08 18:18:37 176

原创 剑指 Offer 66. 构建乘积数组

题目要求不能用除法,所以只能用乘法,如果每一个B[i]直接乘的话会有很多重复计算,费时所以可根据题意 可构建一个矩阵,分为上下两个三角区域下三角区域中,b[n] = b[n-1] * a[n-1]上三角区域中,b[n] = b[n-+] * a[n+1]这样递推可以有效地避免重复计算最后上三角的b[n] 乘上下三角的b[n],就得到结果public int[] constructArr(int[] a) { if (a.length == 0) return new int[0

2021-12-08 18:11:07 503

原创 剑指 Offer 12. 矩阵中的路径

回溯 剪枝回溯题,套模板这道题中,走过的路用一个特殊的字符进行标记,用来作为路径选择的判断条件具体思路看注解public class Offer12 { public boolean exist(char[][] board, String word) { /** 从网格的任意一个地方开始遍历寻找,也就是当前的ij位置上的字符是否为word的第一个字符,如果是说明该路径起点有戏,否则连起点都不对还是换一个起点吧*/ for (int i = 0; i &l

2021-12-08 17:57:40 56

原创 剑指 Offer 38. 字符串的排列

回溯很标致的一道回溯题照着模板写就行没有用剪枝具体的流程注解里面有public class Offer38 { public String[] permutation(String s) { HashSet<String> result = new HashSet<>();// ArrayList<String> result = new ArrayList<>();//结果集 String

2021-12-08 16:17:09 143

原创 剑指 Offer 48. 最长不含重复字符的子字符串

用滑动窗口主要注意滑动窗口的滑动的条件用两个指针,从最左边开始,右指针向右移动,并且右指针移动后,将对应字符存入set中,当右指针指向的字符已经存在set中时,就移动左指针,然后set删去左指针对应的字符,直到set中没有右指针对应的字符时,左指针停止移动public class Offer48 { /** 滑动窗口,*/ public int lengthOfLongestSubstring(String s) { /** 先将字符串转化为字符数组*/

2021-12-08 16:04:57 540

原创 剑指 Offer 26. 树的子结构

递归套递归一开始思路是 在 创建一个函数,进行在A中查找和B的根节点相同的结点,然后再创建一个函数,用来比较刚才在A中找到的子树和B树是否一样提交时发现,给的二叉树可能存在结点值相同,所以就只能 一旦找到A中和B的根节点相同的结点 后,就开始比较 A中子树和B是否一样public class Offer26 { public boolean isSubStructure(TreeNode A, TreeNode B) { /** 终止条件 : 穿过叶子结点 或者 如果当前

2021-12-06 10:58:09 596

原创 剑指 Offer 36. 二叉搜索树与双向链表

二叉搜索树的中序遍历是有序的,所以可以在中序遍历的基础上进行添加将中序遍历中的输出结点替换为本题所需要的结点中间的连接(具体看注解)public class Offer36 { /** 二叉搜索树的中序遍历是有序的,所以可以在中序遍历的基础上进行添加*/ /** 设立两个辅助指针,一个用来指向当前结点,一个指向上一个结点*/ private Node pre; private Node head; public Node treeToDoublyList(No

2021-12-05 20:37:23 135

原创 剑指 Offer 34. 二叉树中和为某一值的路径

深度优先 回溯法public class Offer34 { /** 先创建一个List用来存放路径*/ private List<List<Integer>> result = new ArrayList<>();//结果集 private List<Integer> path = new ArrayList<>();//设置一个变量,来判断目前路径是否满足目标路径 public List<List&

2021-12-05 19:14:41 394

原创 剑指 Offer 31. 栈的压入、弹出序列

建立一个辅助栈向辅助栈中放入pushed栈中的元素同时查找栈顶的元素 (根据popper数组的指针指向的数)如果没有找到就继续入栈,如果找到就出栈,并且吧指针向后移动当全部入栈时候,结束public boolean validateStackSequences(int[] pushed, int[] popped) { /** 建立一个辅助栈*/ Stack<Integer> stack = new Stack<>(); /

2021-12-04 18:08:53 624

原创 剑指 Offer 46. 把数字翻译成字符串

动态规划思路:其实和青蛙跳台阶一个道理当有 n 个数的排列方式为1. 第n个数字无法和前面的数字无法组合时排列方式为:前 n-1个数的排列方式 加上当前数字,数量为 fn-1(前n-1个数字饿排列方式)2. 第n个数字可以和前面的数字组合时排列方式为: 前 n-1个数的排列方式 加上当前数字,数量为 fn-1(前n-1个数字饿排列方式)和 前n-2个数的排列方式 (fn-2)两种情况,只需要判断 第n个数字是否可以和前面的数字组合如果组合的数字为 10 到 25 就说明可以组合转移方程:

2021-12-04 12:37:11 61

原创 剑指 Offer 49. 丑数

动态规划 三指针思想:在已有的丑数序列上每一个数都必须乘2, 乘3, 乘5,然后选取其中最小的丑数,这样才不会漏掉某些丑数,初始化: 第一个丑数为1,arr[0] = 1转移方程: 丑数 == 某较小丑数 × 某因子 即 min = (a2,b3,c*5)最优子结构: arr[a],arr[b],arr[c]来自k神的图/** 动态规划 三指针*/ public int nthUglyNumber(int n) { if (n == 0) return 0

2021-12-04 10:09:54 425

原创 剑指 Offer 14- I. 剪绳子

贪心 * 思想:当n大于4时,尽可能多的剪出长度为3的段,3就是最优的, * 当 n 被剪到小于4时,就不用再减,因为小于4时剪还不如不剪 * 如果给的n直接就小于4,没办法,特殊值,特殊处理,不剪也得剪 public int cuttingRope(int n) { if (n == 2) return 1; if (n == 3) return 2; if (n == 4) return 4; int res = 1;

2021-11-30 20:50:31 56

原创 剑指 Offer 33. 二叉搜索树的后序遍历序列

因为是搜索二叉树,所以 左结点 < root < 右结点先遍历找到 大于数组最后一个数(也就是root)的索引则 [left,i-1]为右子树的区间,[i,right-1]为左子树的区间判断右子树区间内的数是否都小于 root(也就是postorder[right])判断左子树区间内的数是否都大于 rootpublic class Offer33 { private int[] postorder; public boolean verifyPostorder(int

2021-11-30 20:13:06 333

原创 剑指 Offer 07. 重建二叉树

整体思想为:先通过先序找到中序中root的位置,再通过中序root的位置找到左子树的区间,和右子树的区间递归左右子树当穿过叶子结点结束public class Offer07 { /** 先通过先序找到中序中root的位置, * 再通过中序root的位置找到左子树的区间,和右子树的区间 * 递归左右子树 * * 当穿过叶子结点结束 * */ private HashMap<Integer,Integer> map

2021-11-30 17:13:47 55

原创 剑指 Offer 04. 二维数组中的查找

有点类似于二叉树了,从左上角开始,通过不断判断,将边界缩小(类似于这一题顺时针打印列表 https://blog.csdn.net/HUIEX/article/details/121564439) /** 从右上角开始,往下变大,往右边小*/ /** 设置边界 up,down,left,right ,当up < down,right < left,结束查找,即没有找到*/ /** 如果目标数小于当前数,就向右移动,如果目标数大于当前数,就像下移动*/ public

2021-11-29 21:29:21 138

原创 剑指 Offer 62. 约瑟夫环问题(动态规划法)

https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/javajie-jue-yue-se-fu-huan-wen-ti-gao-su-ni-wei-sh/fx = (fx + m) % i;转移方程就直接记住吧,可以照着这个图去穷举分析,理解一下这个方程 /** 动态规划 /数学解法 约瑟夫环*/ public int lastRemaining(int n, in

2021-11-29 21:22:10 206

原创 剑指 Offer 62. 约瑟夫环问题(模拟法)

不建议使用,时间复杂度太大,这个用了1361ms用ArrayList会稍快一些模拟时,重点在于 如何计算要删除数字的坐标,具体看注解/** 模拟法*/ public int lastRemaining(int n, int m) { /** 创建一个集合用来模拟环*/ ArrayList<Integer> list = new ArrayList<>(); for (int i = 0; i < n; i++){

2021-11-29 21:15:48 182

原创 剑指 Offer 53 - II. 0~n-1中缺失的数字

二分法,主要是边界的细节,无了 public int missingNumber(int[] nums) { if (nums.length == 0) return 0; /** 判断nums[mid] 是否等于 mid * 如果等于mid,那么这个数字在 [mid+1,right]区间内 * 如果不等于mid,就在 [left,mid-1]*/ int left = 0; int right

2021-11-29 19:05:05 103

原创 剑指 Offer 53 - I. 在排序数组中查找数字 I

先用二分找到目标数字,同时也缩小了区间再用遍历找到目标区间的边界/** 典型二分,说了有序数组*/ public int search(int[] nums, int target) { /** 先确立好边界*/ int left = 0; int right = nums.length - 1; /** 开始二分,当left > right 时结束*/ while (left <= right){

2021-11-29 18:50:46 143

原创 剑指 Offer 18. 删除链表的节点

注意判断链表的第一个结点(也就是head结点)是否为目标结点和链表最后一个结点(因为用的是但指针,无法判断最后一个结点),需要在跳出循环后单独判断public class Offer18 { public ListNode deleteNode(ListNode head, int val) { if (head == null) return null; /** 找到目标结点的前一个结点temp*/ ListNode temp = head;

2021-11-29 16:33:39 37

原创 剑指 Offer 11. 旋转数组的最小数字

二分查找,范围逼近 减治思想当 nums[mid]小于最右边的数,说明旋转点在[left,mid]的区间内 ,将查找区间的右边界变为mid(细节)当 nums[mid]大于最右边的数,说明旋转点在[mid+1,right]的区间内,将将查找区间的左边界变为mid+1当 nums[mid]等于最右边的数,就将right–,缩小范围,因为 right–并不会结果产生影响,为什么? 因为right–的前提条件为nums[mid] = nums[right],那么该nums[right]一定不为旋转点最后

2021-11-29 11:00:16 227

原创 剑指 Offer 63. 股票的最大利润

当前天数的最大利润为 Math.max(前一天的最大利润,这一天的价钱减去前几天最小的价钱)从第二天开始算起,也就是 i = 1; /** 当前天数的最大利润为 Math.max(前一天的最大利润,这一天的价钱减去前几天最小的价钱)*/ public int maxProfit(int[] prices) { if (prices.length == 0) return 0; /** 初始状态: 第一天的最大利润为 0 */ int fn =

2021-11-27 20:51:40 49

原创 剑指 Offer 10- II. 青蛙跳台阶问题(动态规划法)

使用动态规划老三步初始状态: f1 = 1,f2 = 2转移方程: fn+1 = fn + fn-1fn = fn-1 + fn-2最优子结构: fnpublic int numWays(int n) { /** 初始状态: f1 = 1,f2 = 2 * 转移方程: fn+1 = fn + fn-1 * fn = fn-1 + fn-2 * 最优子结构: fn **

2021-11-27 17:21:40 126

原创 剑指 Offer 10- I. 斐波那契数列

典型动态规划老三步初始状态: f[1] = 1,f[0] = 0转移方程: f[n+1] = f[n] + f[n-1]f[n] = f[n-1] + f[n-2];最优子结构: f[n]注意一下题目要求的取模public int fib(int n) { /** 初始状态: f[1] = 1,f[0] = 0 * 转移方程: f[n+1] = f[n] + f[n-1] * f[n] = f[n-

2021-11-27 17:19:18 117

原创 剑指 Offer 42. 连续子数组的最大和

看题目感觉是动态规划然后列举分析一下,发现 过程中有些结果是重叠的规律为 nums中索引为n的数,其子数组最大值为 Math.max(索引为 n-1的最大子数组加上自己本身(数组中该索引本身的数),自己本身)得出:初始状态:f0 = nums[0]转移方程:fn+1 = fn + nums[n+1] 或 fn+1fn = fn-1 + nums[n] 或 fn最优子结构:fn/** 到索引为n的数,其子数组最大值为 索引为 Math.max(n-1的最大子数组加上自己,自己本身)*/

2021-11-27 17:16:46 187

原创 剑指 Offer 30. 包含min函数的栈

用链表实现一个栈重点在结点中设置一个min属性,用来存放当前结点和它下面栈元素的最小值还有就是利用头插法,简单方便public class Offer30 { private Node head; public Offer30() { } public void push(int x) { //如果当前栈为空 就让头结点指向当前结点,最小值为x if (head == null) head = new Node(x,x,nul

2021-11-27 14:58:40 219 1

原创 剑指 Offer 55 - II. 平衡二叉树

使用递归,终止条件:穿过叶子结点,root == null;子问题和问题的关系:左子树深度与右子树深度的差值小于1,并且左右子树也都为平衡二叉树/** 递归,终止条件:穿过叶子结点,root == null; 子问题和问题的关系:左子树深度与右子树深度的差值小于1,并且左右子树也都为平衡二叉树 * 当前方法为 传入结点,返回该结点下的树是否为平衡二叉树*/ public boolean isBalanced(TreeNode root){ if (root == nu

2021-11-27 13:40:43 153

原创 剑指 Offer 47. 礼物的最大价值

用动态规划找规律,确定最优子结构 :当前格子的累计最大价值为 上面和左边 的 最大累计价值 加上 当前格子的价值即:dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]) + grid[i][j]确定边界:第一个格子的最大累计价值就是当前格子价值public int maxValue(int[][] grid) { /** 创建一个dp矩阵,用来存放到达单元格 (i,j)(i,j) 时能拿到礼物的最大累计价值。(可以理解为记事本)

2021-11-26 21:27:02 43

原创 剑指 Offer 28. 对称的二叉树

public boolean isSymmetric(TreeNode root) { /** 特殊条件 root == null*/ if (root == null) return true; return is(root.left,root.right); } public boolean is(TreeNode left,TreeNode right){ /** 递归终止条件 * 左边和右边结点都.

2021-11-26 17:36:14 234

原创 剑指 Offer 29. 顺时针打印矩阵

主要是思想,利用边界进行打印和判断结束,实现起来不难,大部分简单题主要就是思路,实现都不难,思路的话如果以后碰见类似的题就能做出来沿着边界打印,即将元素按顺序添加到result边界向内收缩 (代表已被打印);判断边界是否相遇,若相遇说明打印完毕,结束打印public int[] spiralOrder(int[][] matrix) { if (matrix.length == 0) return new int[0]; int[] result = new int[

2021-11-26 17:21:35 427

原创 剑指 Offer 09. 用两个栈实现队列

从题目代码给的注解可以得出题意为创建一个类,CQueue,可以实现队列,要求使用两个栈来完成题目给了一个构造器,一个添加方法,一个删除方法(给个输入输出案例属实没有看懂)总体思想为两个栈,一个用来添加元素,当删除元素时,就将第一个栈的元素添加到另一个栈中,根据栈的特性,第二个栈的栈顶恰巧为加入的第一个元素;当再添加元素时,就继续加入第一个栈;当再删除元素时,就分为三种情况 :第二个栈为空,就将第一个栈依次出栈,加入到第二个栈中,再将第二个栈出栈一个元素第二个栈不为空,就将第二个栈出栈一个元

2021-11-26 14:37:27 49

原创 剑指 Offer 45. 把数组排成最小的数

排序题主要问题就是如何排序,排序的规则(o1+o2).compareTo(o2+o1)即 判断两个数不同顺序相加比较大小整体思路流程在注解中加油 public static String minNumber(int[] nums) { /** 将整数数组转换为字符串数组*/ String[] strArr = new String[nums.length]; int i = 0; for (int num :

2021-11-25 16:57:54 49

原创 剑指 Offer 40. 最小的k个数(堆排序法)

用sort的方法就不写了,没有什么意义下面代码为堆排序的解法思路都在代码注解中了,用堆挺简单的,还是调用API,没什么要说的注意要重优先队列的比较方法public int[] getLeastNumbers(int[] arr, int k) { if (k == 0){ return new int[0]; } /** 创建一个大根堆,size为k,将数组元素存入堆中, * 如果比堆顶还要到,就直接跳过,

2021-11-25 15:28:41 55

原创 剑指 Offer 03. 数组中重复的数字

用HashMap的解法就不多说了另一种解法 原地交换 空间复杂度为1 public int findRepeatNumber(int[] nums) { /** 如果该数组没有重复的数时,每一个索引都对应着唯一的那个数 * 但是现在一个数对应多个索引 * 通过交换,使索引和数值一一对应,做到类似于字典的作用*/ int i = 0; while (i < nums.length){

2021-11-24 19:41:55 266

原创 剑指 Offer 39. 数组中出现次数超过一半的数字

用个map就搞定了,注意lenght为1 时的情况先判断是否有这个key,如果没有value设为1如果有 value+1public static int majorityElement(int[] nums) { /** 创建一个HashMap key用来存放数组元素,value用来存放出现次数*/ if (nums.length == 1){ return nums[0]; } HashMap<Inte

2021-11-24 16:55:19 252

原创 剑指 Offer 61. 扑克牌中的顺子

就直接暴力就可以了,就5个数设置一个标记,用来记录大小王的数二种情况如果有两个牌相同,就直接返回如果两个牌之间的跨度超过了王牌的数量,也直接返回truepublic static boolean isStraight(int[] nums) { /** 先将nums排序*/ Arrays.sort(nums); int mark = 0; /** for循环判断是否连续 如果为0 直接跳过*/ for (int

2021-11-24 15:37:45 247 1

Redis_Huiex.md

Redis

2021-11-05

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

TA关注的人

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