数据结构与算法专辑
躬身算法至天明,不知东方之既白。
你走吧起风了__
孤独本是常态,逢人何必言深。
展开
-
蓝桥杯-第十一届JavaB组省赛真题---》”解密“问题
1. 解密问题描述:小明设计了一种文章加密的方法:对于每个字母 C,将它变成某个另外的字符 Tc 。下表给出了字符变换的规则:例如,将字符串 YeRi 加密可得字符串 EaFn。小明有一个随机的字符串,加密后为EaFnjISplhFviDhwFbEjRjfIBBkRyY(由 30个大小写英文字母组成,不包含换行符),请问原字符串是多少?(填空题5分)答案:YeRikGSunlRzgDlvRwYkXkrGWWhXaA/** * @Date 2020/11/18 18:42 * @Ver原创 2020-11-18 18:51:13 · 647 阅读 · 0 评论 -
彻底玩转单例模式
饿汉式// 饿汉式单例 public class Hungry { // 可能会浪费空间 private byte[] data1 = new byte[1024*1024]; private byte[] data2 = new byte[1024*1024]; private byte[] data3 = new byte[1024*1024]; private byte[] data4 = new byte[1024*1024]; private Hungry(){ }.原创 2021-05-07 14:52:11 · 114 阅读 · 0 评论 -
LeetCode.p110--平衡二叉树
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) {...原创 2021-02-03 17:51:22 · 101 阅读 · 0 评论 -
P96.不同的二叉搜索树
class Solution { public int numTrees(int n) {int[] G = new int[n + 1]; G[0] = 1; G[1] = 1; for (int i = 2; i <= n; ++i) { for (int j = 1; j <= i; ++j) { G[i] += G[j - 1] * G[i - j]; .原创 2021-01-17 17:05:09 · 65 阅读 · 0 评论 -
KMP算法的实现与解析
KMP 算法介绍KMP是一个解决模式串在文本串是否出现过,如果出现过,最早出现的位置的经典算法 Knuth-Morris-Pratt 字符串查找算法,简称为 “KMP算法”,常用于在一个文本串S内查找一个模式串P的出现位置,这个算法由Donald Knuth、Vaughan Pratt、James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法. KMP方法算法利用之前判断过信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到,原创 2021-01-16 15:54:31 · 181 阅读 · 0 评论 -
LeetCode算法解析之“二叉树最大深度”问题
class Solution { public int maxDepth(TreeNode root) { // if(root==null) // return 0; // int leftHeight = maxDepth(root.left); // int rightHeight = maxDepth(root.right); //.原创 2021-01-16 12:19:45 · 111 阅读 · 0 评论 -
LeetCode算法解析之“二叉树最小深度”问题
class Solution { public int minDepth(TreeNode root) { if(root == null) return 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int high =1; wh...原创 2021-01-16 12:12:46 · 93 阅读 · 0 评论 -
LeetCode算法解析之“中序遍历”问题
实现代码如下:class Solution { public List<Integer> inorderTraversal(TreeNode root) { ArrayList<Integer> res = new ArrayList<>(); midOrde(root,res); return res; } public void midOrde(TreeNode r...原创 2021-01-13 19:52:36 · 136 阅读 · 0 评论 -
LeetCode算法解析之“零钱兑换”问题
public class Solution { public int coinChange(int[] coins, int amount) { int max = amount + 1; int[] dp = new int[amount + 1]; Arrays.fill(dp, max); dp[0] = 0; for (int i = 1; i <= amount; i++) { ..原创 2021-01-13 19:16:16 · 196 阅读 · 0 评论 -
LeetCode算法解析之“分发糖果“问题
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。你需要按照以下要求,帮助老师给这些孩子分发糖果:每 个孩子至少分配到 1 个糖果。评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。那么这样下来,老师至少需要准备多少颗糖果呢?解题思路:规则定义: 设学生 AA 和学生 BB 左右相邻,AA 在 BB 左边;左规则: 当 ratings_B>ratings_Aratings ,时B 的糖比 A 的糖数量多。右规则: 当 rating.原创 2020-12-28 16:30:20 · 182 阅读 · 0 评论 -
LeetCode算法解析之“二叉树的层序遍历”问题
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Solution { public L..原创 2020-12-22 19:40:58 · 59 阅读 · 0 评论 -
BFS 的使用场景总结:层序遍历、最短路径问题
今天在刷LeetCode算法题的时候,看到一篇非常好的解析,分享给大家。BFS算法的实现与应用场景详解原创 2020-12-22 19:19:17 · 153 阅读 · 1 评论 -
LeetCode算法解析之“反转图像”问题。
给定一个 n × n 的二维矩阵表示一个图像。 将图像顺时针旋转 90 度。说明:你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。方法一:使用辅助数组代码实现:class Solution { public void rotate(int[][] matrix) { int i =matrix.length; int j =matrix[0].length; ..原创 2020-12-19 16:50:09 · 160 阅读 · 1 评论 -
LeetCode算法解析之“重排链表”问题
给定一个单链表 L:L0→L1→…→Ln-1→Ln , 将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。示例 1:示例 2:解题思路如下:因为链表不支持下标访问,所以我们无法随机访问链表中任意位置的元素。因此比较容易想到的一个方法是,我们利用线性表存储该链表,然后利用线性表可以下标访问的特点,直接按顺序访问指定元素,重建该链表即可。class Solution { public void..原创 2020-12-19 12:17:47 · 200 阅读 · 1 评论 -
LeetCode算法解析之“K个一组翻转链表问题”
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。解题思路:我们需要把链表结点按照 k 个一组分组,所以可以使用一个指针 head 依次指向每组的头结点。这个指针每次向前移动 k步,直至链表结尾。对于每个分组,我们先判断它的长度是否大于等于 k。若是,我们就翻转这部分链表,否则不需要翻转。接下来的问题就是如何翻转一个分组内的子链表。翻转一个链表并不难,过程可..原创 2020-12-15 19:20:11 · 124 阅读 · 1 评论 -
Java实现堆排序和图解
堆排序:堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:大顶原创 2020-12-11 17:26:14 · 169 阅读 · 0 评论 -
二叉树的前中后序遍历及其实现
二叉树的全部代码叶子节点的定义//先创建 HeroNode 结点class HeroNode { private int no; private String name; private HeroNode left; // 默认null private HeroNode right; // 默认null public HeroNode(int no, String name) { this.no = no; this.name = name; } public int g原创 2020-12-10 14:16:02 · 109 阅读 · 0 评论 -
Arrays.sort方法的底层实现原理
最近在刷算法题的过程中,频频用到Arrays.sort()这个排序API,所以我就想看一看这个方法的底层到底是采用什么排序策略。和我一起来看看吧!// Use Quicksort on small arraysif (right - left < QUICKSORT_THRESHOLD){ //QUICKSORT_THRESHOLD = 286 sort(a, left, right, true); return; }数组一进来,会碰到第一个阀原创 2020-12-10 14:07:00 · 2148 阅读 · 0 评论 -
回溯算法原理详解
小伙伴们大家好,今天推荐一篇质量极高的博文,讲的是回溯算法的原理与解析,我仔细看了一下,讲的非常好,推荐一波。回溯算法详解原创 2020-12-09 19:04:11 · 538 阅读 · 0 评论 -
LeetCode算法解析之“不同路径”问题
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径?我们令 dp[i][j] 是到达 i, j 最多路径动态方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]注意,对于第一行 dp[0][j],或者第一列 dp[i][0],由于都是在边界,所以只能为 1时间复杂度:O(m*n)O(m∗n)空间..原创 2020-12-09 18:59:18 · 216 阅读 · 0 评论 -
LeetCode算法解析之“贪心”解决反转矩阵最大得分问题
有一个二维矩阵 A 其中每个元素的值为 0 或 1 。移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1 都更改为 0。在做出任意次数的移动后,将该矩阵的每一行都按照二进制数来解释,矩阵的得分就是这些数字的总和。返回尽可能高的分数。贪心思想:根据题意,能够知道一个重要的事实:给定一个翻转方案,则它们之间任意交换顺序后,得到的结果保持不变。因此,我们总可以先考虑所有的行翻转,再考虑所有的列翻转。不难发现一点:为了得到最高的分数,矩阵的每一行的最左边的..原创 2020-12-07 20:14:25 · 423 阅读 · 0 评论 -
LeetCode算法解解析之杨辉三角
给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。class Solution { public List<List<Integer>> generate(int numRows) { List<List<Integer>> ret = new ArrayList<List<Integer>>(); for (int i = 0; i < numRows; +.原创 2020-12-07 19:08:54 · 85 阅读 · 0 评论 -
插值查找算法的实现与原理解析
插值查找基本介绍插值查找算法类似于二分查找, 不同的是插值查找每次从自适应 mid 处开始查找。插值查找图解将折半查找中的求 mid 索引的公式 , low 表示左边索引 left ,high 表示右边索引 right ,key 就是前面我们讲的 findVal图中公式:int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;大致思路和二分查找一样,有如下不同:1.寻找 mid 公式不同:i原创 2020-12-07 16:18:29 · 952 阅读 · 0 评论 -
二分查找算法的实现与原理解析
二分查找思路二分查找算法的前提:数组必须是有序数组二分查找算法思路分析(递归版):定义两个辅助指针:left、right ,待查找的元素在 arr[left]~arr[right] 之间 left 初始值为 0 ,right 初始值为 arr.length - 1将数组分成两半:int mid = (left + right) / 2; ,取数组中间值与目标值 findVal 比较如果 mid > findVal ,说明待查找的值在数组左半部分如果 mid < findVal原创 2020-12-07 16:14:35 · 325 阅读 · 0 评论 -
插入排序算法的实现与原理解析
插入排序基本介绍插入式排序属于内部排序法, 是对于欲排序的元素以插入的方式找寻该元素的适当位置, 以达到排序的目的。插入排序思想插入排序(Insertion Sorting) 的基本思想是: 把 n 个待排序的元素看成为一个有序表和一个无序表开始时有序表中只包含一个元素, 无序表中包含有 n-1 个元素, 排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较, 将它插入到有序表中的适当位置, 使之成为新的有序表插入排序图解插入排序逻辑:首先,将数组分为原创 2020-12-05 15:43:32 · 1296 阅读 · 1 评论 -
基数排序算法的实现与原理详解
基数排序基本介绍基数排序(radix sort) 属于“分配式排序” (distribution sort) , 又称“桶子法” ( bucket sort) 或 bin sort, 顾名思义, 它是通过键值的各个位的值, 将要排序的元素分配至某些“桶” 中, 达到排序的作用基数排序法是属于稳定性的排序, 基数排序法的是效率高的稳定性排序法基数排序(Radix Sort)是桶排序的扩展基数排序是 1887 年赫尔曼· 何乐礼发明的。 它是这样实现的: 将整数按位数切割成不同的数字, 然后按每个位数原创 2020-12-05 14:49:05 · 424 阅读 · 0 评论 -
希尔排序算法的实现与解析
简单插入排序问题我们看简单的插入排序可能存在的问题,数组 arr = { 2, 3, 4, 5, 6, 1 } 这时需要插入的数 1(最小),简单插入排序的过程如下{2,3,4,5,6,6}{2,3,4,5,5,6}{2,3,4,4,5,6}{2,3,3,4,5,6}{2,2,3,4,5,6}{1,2,3,4,5,6}结论: 当需要插入的数是较小的数时, 后移的次数明显增多, 对效率有影响希尔排序基本介绍希尔排序是希尔(Donald Shell) 于 1959 年提出的一种排序算法。原创 2020-12-03 17:19:43 · 249 阅读 · 0 评论 -
归并排序算法实现与解析
归并排序基本介绍归并排序(MERGE-SORT) 是利用归并的思想实现的排序方法, 该算法采用经典的分治(divide-and-conquer)策略分治法将问题分(divide)成一些小的问题然后递归求解, 而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起, 即分而治之归并排序思想归并排序代码思路合并时,其实是拿着原数组(arr)中两个相邻的子数组(arr1、arr2)进行合并,我们使用三个指针,来表示两个子数组在原数组中的位置arr[left] ~ arr[mi原创 2020-12-03 16:53:53 · 214 阅读 · 0 评论 -
LeetCode算法解析之“有序数组查找选定元素位置”问题
要求:给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。你的算法时间复杂度必须控制在O(log n)内!(重点)先给大家看一下我最开始写的“淳朴”的解析。解法一:class Solution { public int[] searchRange(int[] nums, int target) { int[] result =.原创 2020-12-02 15:32:47 · 608 阅读 · 1 评论 -
选择排序算法实现与解析
选择排序选择排序基本介绍选择式排序也属于内部排序法, 是从欲排序的数据中, 按指定的规则选出某一元素, 再依规定交换位置后达到排序的目的。选择排序思想选择排序(select sorting) 也是一种简单的排序方法。 它的基本思想是(n 是数组大小):第一次从 arr[0]~arr[n-1]中选取最小值,与 arr[0] 交换第二次从 arr[1]~arr[n-1]中选取最小值, 与 arr[1] 交换第三次从 arr[2]~arr[n-1]中选取最小值, 与 arr[2] 交换,原创 2020-12-01 17:50:51 · 797 阅读 · 0 评论 -
冒泡排序算法实现与优化
伙伴们大家好,一个多月前写 “快排”文章 时候就说了要写一篇关于最大众化的 “冒泡排序” 文章,今天来履行诺言了,冒泡排序是最基础的排序算法,难度很低,主要用于回忆与记录,如果对你有所帮助,那就再好不过了,直接上正文。冒泡排序基本介绍冒泡排序(Bubble Sorting) 的基本思想是: 通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值, 若发现逆序则交换, 使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。优化: 因为排序的过程中, 各元素不断接近自己的原创 2020-12-01 14:11:49 · 130 阅读 · 0 评论 -
LeetCode算法解析之“三角形最大周长”问题
给定由一些正数(代表长度)组成的数组 A,返回由其中三个长度组成的、面积不为零的三角形的最大周长。如果不能形成任何面积不为零的三角形,返回 0。方法一:贪心 + 排序不失一般性,我们假设三角形的边长满足 a \leq b \leq ca≤b≤c,那么这三条边组成面积不为零的三角形的充分必要条件为a+b>ca+b>c。基于此,我们可以选择枚举三角形的最长边 cc,而从贪心的角度考虑,我们一定是选「小于 cc 的最大的两个数」作为边长 aa 和bb,此时最有可能满足 a+b>.原创 2020-12-01 11:03:12 · 627 阅读 · 0 评论 -
LeetCode算法解析之“四数相加”问题
例如:看到这道题后,我的第一个想法就是“蛮力”解法,也就是直接上四个循环,后面想了想这个解法是很糟糕的,时间复杂度极高!必然会超出时间限制!结果也是如此。以下例子是一个不好的解法(不推荐)class Solution { public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { if(A.length==0 || B.length==0 || C.length==0 || D.length==0).原创 2020-11-27 15:14:42 · 540 阅读 · 0 评论 -
回溯算法之“八皇后问题”详解
递归-八皇后问题(回溯算法 )八皇后问题介绍八皇后问题, 是一个古老而著名的问题, 是回溯算法的典型案例。 该问题是国际西洋棋棋手马克斯· 贝瑟尔于1848 年提出: 在 8× 8格的国际象棋上摆放八个皇后, 使其不能互相攻击, 即: 任意两个皇后都不能处于同一行、同一列或同一斜线上, 问有多少种摆法(92)。代码思路第一个皇后先放第一行第一列第二个皇后放在第二行第一列、 然后判断是否 OK, 如果不 OK, 继续放在第二列、 第三列、 依次把所有列都放完, 找到一个合适继续第三个皇后原创 2020-11-26 15:54:33 · 967 阅读 · 0 评论 -
LeetCode算法解析之“最常见单词”问题
示例:提示:解题思路这是一个简单但很麻烦的题。对于初学者来说,此题可以快速熟悉Java常见集合类型和字符串处理。我最开始的思路很蠢:想要把字符串paragraph遍历一遍处理成小写的且没有banned数组单词的集合a,然后再遍历a,生成一个带计数的表b,最后再遍历b,找到计数值最大的单词。然而这个思路需要遍历三次目标对象且是不同的数据结构(String,ArrayList, HashMap)其实挺麻烦的。然而实际操作时,可以只遍历一次:遍历字符串paragraph的每个字符,只要是字母就.原创 2020-11-26 14:33:27 · 72 阅读 · 0 评论 -
递归算法解决“迷宫”问题
递归-迷宫问题代码思路使用二维数组 map[][] 模拟迷宫约定: 当 map[i][j] 为 0 表示该点没有走过 ;当为 1 表示墙;2 表示通路可以走 ;3 表示该点已经走过,但是走不通setWay() 方法用于找路,true 表示该路可以走通,false 表示该路走不通 在走迷宫时,需要确定一个策略(方法)下->右->上->左 , 一步一步向前试探,如果该点走不通,再回溯每当走到一个点时,将该点置为 2 ,暂时假设该路能走通,至于到底走不走得通,得看后面有没有找原创 2020-11-26 12:55:44 · 1204 阅读 · 0 评论 -
“逆波兰表达式”完整代码实现
逆波兰计算器5.1、计算器说明输入一个逆波兰表达式(后缀表达式), 使用栈(Stack),计算其结果 支持小括号和多位数整数,因为这里我们主要讲的是数据结构, 因此计算器进行简化, 只支持对整数的计算5.2、代码思路计算后缀表达式无需考虑运算符优先级问题,所以只需要一个数栈即可分为两种情况:遇到数:压入数栈遇到运算符:从数栈中弹出两个数,进行计算,计算结果压入数栈5.3、代码实现出栈的两个数:num2 和 num1num2 先出栈,所以 num2 是减数或除数原创 2020-11-25 20:16:37 · 1222 阅读 · 0 评论 -
LeetCode算法解析之“上身下降字符串”问题
给你一个字符串 s ,请你根据下面的算法重新构造字符串:从 s 中选出 最小 的字符,将它 接在 结果字符串的后面。 从 s 剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在结果字符串后面。 重复步骤 2 ,直到你没法从 s 中选择字符。 从 s 中选出 最大 的字符,将它 接在 结果字符串的后面。从 s 剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。 重复步骤 5 ,直到你没法从 s 中选择字符。重复步骤 1 到 6 ,直到 s 中..原创 2020-11-25 16:14:14 · 92 阅读 · 0 评论 -
使用栈结构完成综合计算器的具体实现
综合计算器全部代码代码思路栈分为两个栈:数栈(numStack):存储表达式中的数字符号栈(operStack):存储表达式中的符号扫描表达式(这里并没有考虑括号):对于数: 扫描到数,则直接压入数栈对于运算符: 扫描到运算符,分为如下几种情况:如果符号栈为空,则直接入栈如果符号栈不为空:如果当前扫描到的运算符的优先级 <= 符号栈栈顶的运算符的优先级,说明上次的运算符优先级较高,先执行优先级高的运算从数栈中弹出两个数,根据符号栈栈顶的运算符进行运算(优先级高,就先算出来)原创 2020-11-25 12:44:09 · 110 阅读 · 0 评论 -
LeetCode算法解析之“完全二叉树节点计算”问题
给出一个完全二叉树,求出该树的节点个数。说明:完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第h 层,则该层包含 1~ 2h 个节点。示例:解题思路:解法一:对于没有约束的二叉树而言,可以很简单地想到使用下面这个递归的解法:public int countNodes(TreeNode root) { if (root == null){ return 0.原创 2020-11-24 18:31:14 · 192 阅读 · 0 评论