
算法
Sirius_7
霍格沃兹在读学生
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Go语言中字典树的实现
写在前面字典树在存储、查询方面应用广泛。所以特总结一下,利用GO语言实现字典树。具体实现字典树的实现主要还是基于树形结构,如果只是小写字母的话,那其实字典树是一个26叉树,每个节点最多都可以有26个子节点。从而可以利用一个长度为26的数组来记录某个节点的子节点情况。并且每个节点可以使用一个布尔标志位来划定是否是一个单词,这是关键所在,具体代码见下:type Trie struct { children [26]*Trie isEnd bool}func Construct原创 2021-05-23 16:49:15 · 402 阅读 · 2 评论 -
Go语言中的自定义slice排序
写在前面排序算法在日常生活中经常用到,许多语言有着很方便的api进行对排序算法的快速支持,譬如JAVA等中的lambda表达式,可以快速将自定义的排序规则织入。slice作为Go语言中特殊的数据结构,其排序的场景是比较常见的。Slice排序Go语言中的sort.slice可以利用匿名函数来快速实现自定义的排序。其实其很类似于其他语言中的sort函数,通过利用lambda表达式实现自定义排序,只不过这里是通过一个匿名函数。具体使用,见一个算法案例。案例分析给定一个字符串数组,和一个整数K,返回这个字原创 2021-05-20 20:37:00 · 1960 阅读 · 0 评论 -
GO语言实现拓扑排序-2
本次主要利用BFS实现拓扑排序在上一篇文章中,主要是利用BFS实现了拓扑排序。与DFS实现拓扑排序不一样的是,DFS主要采用递归的方式实现拓扑排序,而BFS则无需引入递归,其核心思想是对一个有向(有环)图的各个节点入度的判断与分析。核心代码func findOrder(numCourses int, prerequisites [][]int) []int { var ( //描述有向图 edges = make([][]int, numCourses)原创 2021-04-01 11:04:56 · 308 阅读 · 0 评论 -
Go语言实现拓扑排序-1
写在前面所谓算法,一定一定是要落地才有意义的,任何一个在计算机领域流行的算法,一定有与之深度match的业务场景。这里之所以总结拓扑排序,是因为拓扑排序的应用场景还是非常丰富的。拓扑排序应用场景从经典的(人人都刷过)的课程表排课问题,到任何一些存在前驱和后驱关系的元素排序问题,其实都是典型的拓扑排序问题。如果细化问题,拓扑排序更多时候是有向图遍历或者排序。Go语言实现拓扑排序业务需求n门课程,其各个课程之间的有的课程需要先修,对应关系以map给出,例如:“信号与系统”:{"通信原理",“线性代原创 2021-03-30 10:15:53 · 371 阅读 · 0 评论 -
Raft算法详解
为什么会有这篇总结留下这篇总结的原因还是因为MIT6.824课程,分布式系统中的Raft算法是非常重要的,首先给出一篇很好的参考博客,供自己以后查看。持续更新…原创 2021-02-23 10:25:09 · 201 阅读 · 0 评论 -
Java HashMap中的getOrDefault(key, defaultValue)方法以及一些思考
写在前面其实最近发现很多api虽然使用的不是太多,但是真的还蛮有用的,可以极大的节省代码空间,避免代码冗余的情况发生。getOrDefault(key, defaultValue)这个api其实是在hashmap还比较常用的,从map中去取一个值的时候,如果该值存在,那么就返回该值对应的value,反之如果不存在,那么将会返回默认值:defaultvalue在一些特定的场景中,或者说特定的数据结构中这个api还是非常好用的。应用实例以力扣381题为例子说一下吧:题干设计一个支持在平均 时间复原创 2020-10-31 22:12:17 · 903 阅读 · 0 评论 -
希尔排序---一种特殊的插入排序(Java实现)
什么是希尔排序希尔排序也是一种插入排序,属于直接插入排序的增强,也被称为缩小增量的插入排序。基本思想希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。我们来看下希尔排序的基本步骤,在此我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2…1},称为增量序列。希尔排序的增量序列的选择与证明是个数学难原创 2020-08-16 16:42:38 · 327 阅读 · 0 评论 -
剑指offer系列-----item53 判断一个树是否为对称二叉树
题干:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。思路:思路1:做出此二叉树的镜像二叉树,和原二叉树进行对比,完全一样那么是对称的,反之不是思路2:就直接按照对称二叉树的定义逐层比较即可,这里使用第二种方法具体解法:class Solution { public boolean isSymmetric(TreeNode root) { return (root==null || judge(root.le原创 2020-05-31 16:10:06 · 127 阅读 · 0 评论 -
剑指offer系列-----item52 找出二叉树的下一个节点
题干:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针,即node.next的最终所指一定是二叉树的根节点。思路:思路1:首先中序遍历这个二叉树,然后把节点按照顺序放入到list内部,然后再根据传入的node进入到list中找下一个节点即可。思路2:直接一边中序遍历,一边找这个值,那么时间复杂度为O(N),空间复杂度可以降到O(1),主要的方法就是分情况进行讨论即可。具体的规律可以总结如下:仔细观察,可以把中原创 2020-05-31 16:06:21 · 130 阅读 · 0 评论 -
剑指offer系列-----item51 判断一个链表是否有环,如有找到入口
题干:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。思路:思路有2:1.利用额外的空间记录链表中的节点,出现重复的节点便是循环入口;2.利用快慢指针,,慢指针一次移动一个节点,快指针是慢指针的速度二倍。二者相遇后,再取一个指针从表头出发,另外一个从相遇节点出发,二者再次相遇的点便是链表中的环入口。这里的思路1,较为简单,直接利用HashMap进行记录即可,关键是思路2,较为抽象,这里给出一个简单的证明:具体解法:方法1:import java.util.Has原创 2020-05-31 15:55:46 · 155 阅读 · 0 评论 -
剑指offer系列-----item50 字符流中第一个不重复的字符
题干:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。思路:思路:其实这道题和输出字符串中第一个不重复的字符是一样的(利用HashMap记录每个字符出现的次数),只不过这里是字符流。换句话说,这里的字符串并不是一次性给好的,而是一个一个输入的,并且输出的第一个只出现一次的字符也原创 2020-05-19 20:08:34 · 149 阅读 · 0 评论 -
剑指offer系列-----item48 构建乘积数组
题干:给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)思路:此题目直接拿暴力法解决的,如果大家有好的方法,欢迎讨论。public class item53 { public static int[] multiply(i原创 2020-05-19 18:10:19 · 132 阅读 · 0 评论 -
剑指offer系列-----item47 输出数组中的重复数字
题干:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。思路:利用hashmap记录每个数字的出现次数即可。这是一道非常简单的题目,故这里也就不再花费太多的时间描述,直接给出解决代码如下:import java.util.HashMap;/*输入一个数组,找出里面有无重复数,有的原创 2020-05-19 17:59:37 · 175 阅读 · 0 评论 -
剑指offer系列-----item46 求两数之和的问题
题干:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。思路:首先可以明确,这种算数运算大部分都可以被位运算去代替。因为在计算机中是只有二进制数的,所有的加减乘除本身也是对二进制数的操作。具体我们来总结一下这道题的思路:不用加减乘除做加法题目描述写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号1、位运算1.解题思路使用位运算实现加法1、一位加法普通加法异或1 + 1 = 01 ^ 1 = 0(错误)1 + 0 = 11原创 2020-05-19 17:57:45 · 150 阅读 · 0 评论 -
剑指offer系列-----item46 求累加和问题
题干:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。思路:如能使用乘除法,那么求和公式搞定。不能就要使用短路法进行解决:ublic class Solution { public int Sum_Solution(int n) { int sum=n; boolean b = (n>0) && ((sum+=Sum_Solution(n-1))&g原创 2020-05-16 15:55:41 · 159 阅读 · 0 评论 -
剑指offer系列-----item45 围成圈报数的问题
题干:有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)思路:实现围成一个圈,那么肯定是要循环的。循环的思路我认为有二:(1)循环链表;(2)循环队列(队尾出队头再进)这里为了方便原创 2020-05-16 15:43:29 · 190 阅读 · 0 评论 -
剑指offer系列-----item43 扑克牌顺子
题干:LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在原创 2020-05-16 15:40:06 · 132 阅读 · 0 评论 -
剑指offer系列-----item42 反转输入的字符串
题干:将输入的字符串进行反转后输出思路:其实这种题目一看到就会去想到一种数据结构:栈。栈的特性是先进后出,所以将字符串按原顺序入栈之后,再出栈就可以实现该字符串的反转。具体代码如下:public class item43 { public static String ReverseSentence(String str) { Stack<String> reverseStack = new Stack<>(); String [] s原创 2020-05-16 15:14:25 · 117 阅读 · 0 评论 -
你真的懂Java中的浅拷贝和深拷贝么?
写在前面:其实深拷贝和浅拷贝这个概念,不仅仅只是Java中独有的概念,很多地方都适用。目前网上的各种资料,对二者的描述我认为是模糊不清的,甚至有一些是错误的,简直是误人子弟!这篇博客主要是从源码角度总结一下浅拷贝和深拷贝的区别。概述:浅拷贝和深拷贝的概念都是针对对象而言的,且都是可以通过生成一个新的对象完成对原始对象的拷贝。那么区分的关键在什么地方:深、浅二字。1.浅拷贝浅拷贝的实现方法为重写继承制Object类的clone( )方法,见下:protected native Object clo原创 2020-05-12 20:53:55 · 231 阅读 · 1 评论 -
剑指offer系列-----item41 字符串循环左移
题干:汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!思路:直接用StringBuffer进行拼接,具体的拼接方法,要用左移位数对str的长度取余,取余结果为真正的移动位数,时间复杂度在O(n)。具体的代码如下:public class item42 {原创 2020-05-11 22:53:39 · 156 阅读 · 0 评论 -
剑指offer系列-----item40 递增数组中等于目标数的两个数
题干:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。思路:这道题,其实和item39的思路蛮相似的,都是可以利用双指针来解决问题。只不过,item39的双指针是起始二者相邻,而这道题的双指针一个应该在链表首部,另外一个应该在链表末尾。具体代码见下:import java.util.ArrayList;public class item41 { public class Solution { publi原创 2020-05-11 16:54:55 · 159 阅读 · 0 评论 -
剑指offer--item39 连续几个数字等于目标数
题干:小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!思路:这种连续的问题,自然想到双指针加滑动窗口。规定两个指针i,j。这段区域的和用等差数列求和为num即可。如果num<sum,那么要把j增加,即窗口原创 2020-05-11 14:33:15 · 163 阅读 · 0 评论 -
剑指offer系利-----item38 找出数组中唯一的两个只出现一次的数字
题干:一个数组,仅有两个数字出现一次,其他都是两次,找出这两个数字思路:思路:还是和当时的那道题目一样,用HashMap记录每个数字出现的次数,返回唯一两个get为0的数,加个flag分开即可整合以上思路后,源码如下:import java.util.HashMap;/*找出一个数组中的两个唯一出现过一次的数字,其他数组都出现了两次。思路:还是和当时的那道题目一样,用HashMap记录每个数字出现的次数,返回唯一两个get为0的数,加个flag分开即可*/public class item原创 2020-05-10 19:48:30 · 174 阅读 · 0 评论 -
剑指offer系列-----item37 判断一棵树是否为平衡二叉树
题干:输入一棵树,判断其是否为平衡二叉树思路:所以这道题本质思路是递归public boolean IsBalanced_Solution(TreeNode root) { if(root==null){ return true; } if(Math.abs(TreeDepth(root.left)-TreeDepth...原创 2020-05-07 15:17:18 · 167 阅读 · 0 评论 -
剑指offer系列-----item36 树的高度
题干:输入一棵二叉树,输出这棵树的高度。思路:这道题思路有2:1.利用BFS每层遍历时叠加高度因为在树的遍历中,BFS天生具有层级遍历的优势,那么在遍历每层的过程中去叠加一个高度,最后自然可以计算出这个二叉树的总高度。public int TreeDepth1(TreeNode root) { Queue<TreeNode> queue = new Link...原创 2020-05-07 15:13:27 · 110 阅读 · 0 评论 -
剑指offer系列-----item35 一个数组中某个数字出现的个数
题干:这是一道简单题,太简单了我就不写思路了,看源码就都能懂啦~/* 在排序数组中找目标数字出现的个数 一看到了排序,想到二分法,但是是统计个数,我认为不必二分,最差就是个O(n)的时间复杂度 */public class item35 { public int GetNumberOfK(int [] array , int k) { if(array...原创 2020-05-07 15:04:57 · 124 阅读 · 0 评论 -
剑指offer系列-----item34 第一个只出现一次的字符
题干:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).思路:HashMap记录每个字符和出现的频率(就只用1和2即可,省时省力),然后按顺序get,第一个get到1的字符返回即可,或者放一个变量自加,来确定下标。具体代码如下:public class item33 { ...原创 2020-05-07 15:03:17 · 133 阅读 · 0 评论 -
剑指offer系列-----item33 输出第n个丑数
题干:把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。思路:思路比较清晰,也是目前比较流行的一种思路,具体见下:因为这个number只包含2,3,5的因子,所以根据以2,3,5来做判断和维护。令number数组里的第一个元素为1。因为我们要让丑数数列有序,所...原创 2020-05-07 11:19:17 · 143 阅读 · 0 评论 -
剑指offer系列-----item32 把数组排成最小数
题干:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。思路:把数组变成String的list,然后两个两个比较,因为s1+s2的长度和s2+s1的长度是一致的,所以如果s1+s2与s2+s1的大小判断只需要判从首个字符开始即可(所以调用的String类的compar...原创 2020-05-04 16:33:46 · 136 阅读 · 0 评论 -
剑指offer系列-----item31 从1到n个整数中,包含1的个数有几个?
题干:如题所示,从1到n个整数中,包含1的个数有几个?思路:这道题最最直接的思路应该是数学解答方法,即利用纯数学归纳总结出结果。但是有点儿复杂,且容易错。本文中采用递归法,对问题进行解答。首先给出代码如下:public int countDigitOne(int n) { return dfs(n);}private int dfs(int n) { if (...原创 2020-05-04 10:08:27 · 151 阅读 · 0 评论 -
剑指offer系列-----item30 一个数组的最大连续子序列之和
题干:输入一个数组,输出这个数组的最大连续子序列之和。思路:思路有2,第一种传统的动态规划思路。这种可以划分为多个子问题叠加的题目利用动态规划解决是最最经典的思路。具体代码如下:public int FindGreatestSumOfSubArray(int[] array) { int dp[]=new int[array.length]; dp[0]= array[0]...原创 2020-05-04 09:54:16 · 148 阅读 · 0 评论 -
剑指offer系列-----item29 一个数组中最小的K个数
题干:如题所示,输出一个数组中最小的k个数。思路:这道题思路其实很简单,核心就是去排序,所以这道题实际考察的是排序的求解思路。具体见以下三种做法:利用封装的sort函数(懒人法):public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { Arrays.sort(input); ...原创 2020-04-30 15:46:48 · 143 阅读 · 0 评论 -
剑指offer系列-----item28 数组中超过一半的数字
题干:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。思路:思路有2:其一,首先对数组进行排序,然后再利用动态规划解决问题;其二,直接利用摩尔投票法进行问题的解决。具体解法见下:way1:import java.util....原创 2020-04-30 10:32:45 · 132 阅读 · 1 评论 -
剑指offer系列-----item27 字符串的排列(究极无敌多种java回溯+剪枝做法)
题干:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。思路:这道题思路明显,全排列问题的解决核心就是利用回溯法。只不过这道题全排列的结果可能会包含重复的值,所以还需要应用剪枝来去重,所以下面的几种解法都是利用回溯法思想,只不过剪枝的操作略有不同。具体的多种解法见下:...原创 2020-04-28 16:28:29 · 139 阅读 · 0 评论 -
剑指offer系列-----item26 二叉搜索树与双向链表
题干:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路:大致思路,二叉搜索树的中序遍历应该就是有序的,我认为这道题的核心就是二叉树的中序遍历方法。返回到是双向链表,却要求不能有新的节点,那么说明肯定不能创建一个链表了,只能修改指针!先把树的node通过中序遍历形成有序的list,再修改list内部Treenode的指针,前...原创 2020-04-28 16:20:26 · 136 阅读 · 0 评论 -
剑指offer系列-----item25 复制复杂链表
题干:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点:注意此处这个任意一个节点也是属于这个链表中的,这句话很重要!),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)思路:这道题关键就是有两点:1.绝对不能直接将引用指向原头节点:RandomListNode node = ...原创 2020-04-28 16:18:17 · 120 阅读 · 0 评论 -
剑指offer系列-----item24 找出二叉树中路径之和为目标值的所有路径
题干:输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)思路:思路有二:1.将所有的root到叶子节点的路径找出来,建成list,并用val的累加值做key,用后者list当val,再去对比与目标值到hashmap中去找相匹配的key。...原创 2020-04-28 11:11:35 · 352 阅读 · 0 评论 -
剑指offer系列-----item23 判断一个数组是否为二叉查找树的后序遍历
题干:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。思路:二叉搜索树的前序遍历一定是有序的,后序遍历的话,根节点在数组最后,前面的数组分为了比root大和比root小的部分,即root的左右子树。如果就这样递归下去,可以将数组中的每一个数统统遍历完成,那么说明结果为二叉搜索树的后序遍历,反之就不是,具...原创 2020-04-28 11:05:29 · 170 阅读 · 0 评论 -
剑指offer系列-----item22层次遍历二叉树
题干:一层一层的向下遍历二叉树,同一层的话再按照从左向右的顺序进行遍历即可。思路:别扯那么多,这就是二叉树的广度优先遍历:BFS。而广度优先遍历的精髓,或者说实现的原理就是队列,保证数据先进先出:先进左边节点、再进右边节点。从而输出就是先左边节点、再右边节点。(补一句:DFS的核心思想,或者底层原理则是栈,先进后出:先进右节点,再进左节点即可)具体代码如下:public ArrayLi...原创 2020-04-28 10:59:50 · 127 阅读 · 0 评论 -
剑指offer系列-----item21 压栈、出栈顺序判断
题干输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)思路题干中所言的所有的数字都不相等,其实是说明了根据入栈的顺序,出栈顺序是唯一的,判断结...原创 2020-04-27 20:17:30 · 175 阅读 · 0 评论