数据结构
Sirius_7
霍格沃兹在读学生
展开
-
Go语言中字典树的实现
写在前面字典树在存储、查询方面应用广泛。所以特总结一下,利用GO语言实现字典树。具体实现字典树的实现主要还是基于树形结构,如果只是小写字母的话,那其实字典树是一个26叉树,每个节点最多都可以有26个子节点。从而可以利用一个长度为26的数组来记录某个节点的子节点情况。并且每个节点可以使用一个布尔标志位来划定是否是一个单词,这是关键所在,具体代码见下:type Trie struct { children [26]*Trie isEnd bool}func Construct原创 2021-05-23 16:49:15 · 331 阅读 · 2 评论 -
Go语言中的自定义slice排序
写在前面排序算法在日常生活中经常用到,许多语言有着很方便的api进行对排序算法的快速支持,譬如JAVA等中的lambda表达式,可以快速将自定义的排序规则织入。slice作为Go语言中特殊的数据结构,其排序的场景是比较常见的。Slice排序Go语言中的sort.slice可以利用匿名函数来快速实现自定义的排序。其实其很类似于其他语言中的sort函数,通过利用lambda表达式实现自定义排序,只不过这里是通过一个匿名函数。具体使用,见一个算法案例。案例分析给定一个字符串数组,和一个整数K,返回这个字原创 2021-05-20 20:37:00 · 1853 阅读 · 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 · 219 阅读 · 0 评论 -
Java HashMap中的getOrDefault(key, defaultValue)方法以及一些思考
写在前面其实最近发现很多api虽然使用的不是太多,但是真的还蛮有用的,可以极大的节省代码空间,避免代码冗余的情况发生。getOrDefault(key, defaultValue)这个api其实是在hashmap还比较常用的,从map中去取一个值的时候,如果该值存在,那么就返回该值对应的value,反之如果不存在,那么将会返回默认值:defaultvalue在一些特定的场景中,或者说特定的数据结构中这个api还是非常好用的。应用实例以力扣381题为例子说一下吧:题干设计一个支持在平均 时间复原创 2020-10-31 22:12:17 · 809 阅读 · 0 评论 -
希尔排序---一种特殊的插入排序(Java实现)
什么是希尔排序希尔排序也是一种插入排序,属于直接插入排序的增强,也被称为缩小增量的插入排序。基本思想希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。我们来看下希尔排序的基本步骤,在此我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2…1},称为增量序列。希尔排序的增量序列的选择与证明是个数学难原创 2020-08-16 16:42:38 · 271 阅读 · 0 评论 -
<细节向>jdk1.8中HashMap底层链表转红黑树的阈值为什么是8?红黑树转链表为什么是6?
先看源码/* * Implementation notes. * * This map usually acts as a binned (bucketed) hash table, but * when bins get too large, they are transformed into bins of * TreeNodes, each structured similarly to those in * java.util.TreeM原创 2020-08-12 10:51:26 · 2510 阅读 · 4 评论 -
二叉树深度和高度
首先对于一棵树而言,二者无区别虽然深度是从上往下,高度的从下往上。但是对于一颗树而言,其高度和深度均为根节点到叶子节点路径的最大值(经过边条数的最大值)但是对于树中某节点而言,就不一样了对于树中某个节点,其深度为根节点到其的边数,而高度为叶子节点到其最长的边数。默认根节点的深度和叶子节点的高度均为0...原创 2020-08-02 11:08:50 · 500 阅读 · 0 评论 -
一文清晰梳理数据库锁机制
写在前面关于数据库锁机制的问题,目前网上的文章大多条理混乱,没有逻辑,故今天系统的梳理一下,也方便自己日后复习。加锁策略区分首先从大的方向去区分,即加锁策略上区分,分为了乐观锁和悲观锁:乐观锁:顾名思义就是非常乐观,非常相信真善美,每次去读数据都认为其它事务没有在写数据,所以就不上锁,快乐的读取数据,而只在提交数据的时候判断其它事务是否搞过这个数据了,如果搞过就rollback。乐观锁相当于一种检测冲突的手段,可通过为记录添加版本或添加时间戳来实现。悲观锁:对其它事务抱有保守的态度,每次去读数据都原创 2020-07-21 16:27:33 · 97 阅读 · 0 评论 -
从ThreadLocal实际应用实例了解ThreadLocal
ThreadLocal是个啥?首先,官方的解释叫做:线程本地变量。这个解释给绝大部分人都是一头雾水。现在我用尽可能直白的语言来解释一下。ThreadLocal是Thread的属性threadlocals的管理工具,就是将一个变量拷贝给每个线程一份,每个线程对这个变量的操作是彼此独立的,不会相互影响。而threadlocals的底层则是一个ThreadLocalMap,这个Map的底层key值是ThreadLocal的虚引用,而Value则是实际的每个线程的所要使用的变量值。案例一:两个线程不适用Thr原创 2020-06-07 22:02:24 · 134 阅读 · 0 评论 -
剑指offer系列-----item53 判断一个树是否为对称二叉树
题干:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。思路:思路1:做出此二叉树的镜像二叉树,和原二叉树进行对比,完全一样那么是对称的,反之不是思路2:就直接按照对称二叉树的定义逐层比较即可,这里使用第二种方法具体解法:class Solution { public boolean isSymmetric(TreeNode root) { return (root==null || judge(root.le原创 2020-05-31 16:10:06 · 94 阅读 · 0 评论 -
剑指offer系列-----item52 找出二叉树的下一个节点
题干:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针,即node.next的最终所指一定是二叉树的根节点。思路:思路1:首先中序遍历这个二叉树,然后把节点按照顺序放入到list内部,然后再根据传入的node进入到list中找下一个节点即可。思路2:直接一边中序遍历,一边找这个值,那么时间复杂度为O(N),空间复杂度可以降到O(1),主要的方法就是分情况进行讨论即可。具体的规律可以总结如下:仔细观察,可以把中原创 2020-05-31 16:06:21 · 77 阅读 · 0 评论 -
剑指offer系列-----item51 判断一个链表是否有环,如有找到入口
题干:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。思路:思路有2:1.利用额外的空间记录链表中的节点,出现重复的节点便是循环入口;2.利用快慢指针,,慢指针一次移动一个节点,快指针是慢指针的速度二倍。二者相遇后,再取一个指针从表头出发,另外一个从相遇节点出发,二者再次相遇的点便是链表中的环入口。这里的思路1,较为简单,直接利用HashMap进行记录即可,关键是思路2,较为抽象,这里给出一个简单的证明:具体解法:方法1:import java.util.Has原创 2020-05-31 15:55:46 · 100 阅读 · 0 评论 -
剑指offer系列-----item50 字符流中第一个不重复的字符
题干:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。思路:思路:其实这道题和输出字符串中第一个不重复的字符是一样的(利用HashMap记录每个字符出现的次数),只不过这里是字符流。换句话说,这里的字符串并不是一次性给好的,而是一个一个输入的,并且输出的第一个只出现一次的字符也原创 2020-05-19 20:08:34 · 98 阅读 · 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 · 98 阅读 · 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 · 116 阅读 · 0 评论 -
剑指offer系列-----item45 围成圈报数的问题
题干:有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)思路:实现围成一个圈,那么肯定是要循环的。循环的思路我认为有二:(1)循环链表;(2)循环队列(队尾出队头再进)这里为了方便原创 2020-05-16 15:43:29 · 119 阅读 · 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 · 83 阅读 · 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 · 64 阅读 · 0 评论 -
剑指offer系列-----item41 字符串循环左移
题干:汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!思路:直接用StringBuffer进行拼接,具体的拼接方法,要用左移位数对str的长度取余,取余结果为真正的移动位数,时间复杂度在O(n)。具体的代码如下:public class item42 {原创 2020-05-11 22:53:39 · 108 阅读 · 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 · 99 阅读 · 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 · 124 阅读 · 0 评论 -
剑指offer系利-----item38 找出数组中唯一的两个只出现一次的数字
题干:一个数组,仅有两个数字出现一次,其他都是两次,找出这两个数字思路:思路:还是和当时的那道题目一样,用HashMap记录每个数字出现的次数,返回唯一两个get为0的数,加个flag分开即可整合以上思路后,源码如下:import java.util.HashMap;/*找出一个数组中的两个唯一出现过一次的数字,其他数组都出现了两次。思路:还是和当时的那道题目一样,用HashMap记录每个数字出现的次数,返回唯一两个get为0的数,加个flag分开即可*/public class item原创 2020-05-10 19:48:30 · 139 阅读 · 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 · 99 阅读 · 0 评论 -
剑指offer系列-----item36 树的高度
题干:输入一棵二叉树,输出这棵树的高度。思路:这道题思路有2:1.利用BFS每层遍历时叠加高度因为在树的遍历中,BFS天生具有层级遍历的优势,那么在遍历每层的过程中去叠加一个高度,最后自然可以计算出这个二叉树的总高度。public int TreeDepth1(TreeNode root) { Queue<TreeNode> queue = new Link...原创 2020-05-07 15:13:27 · 77 阅读 · 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 · 84 阅读 · 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 · 105 阅读 · 0 评论 -
剑指offer系列-----item29 一个数组中最小的K个数
题干:如题所示,输出一个数组中最小的k个数。思路:这道题思路其实很简单,核心就是去排序,所以这道题实际考察的是排序的求解思路。具体见以下三种做法:利用封装的sort函数(懒人法):public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { Arrays.sort(input); ...原创 2020-04-30 15:46:48 · 89 阅读 · 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 · 102 阅读 · 1 评论 -
剑指offer系列-----item27 字符串的排列(究极无敌多种java回溯+剪枝做法)
题干:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。思路:这道题思路明显,全排列问题的解决核心就是利用回溯法。只不过这道题全排列的结果可能会包含重复的值,所以还需要应用剪枝来去重,所以下面的几种解法都是利用回溯法思想,只不过剪枝的操作略有不同。具体的多种解法见下:...原创 2020-04-28 16:28:29 · 100 阅读 · 0 评论 -
剑指offer系列-----item26 二叉搜索树与双向链表
题干:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路:大致思路,二叉搜索树的中序遍历应该就是有序的,我认为这道题的核心就是二叉树的中序遍历方法。返回到是双向链表,却要求不能有新的节点,那么说明肯定不能创建一个链表了,只能修改指针!先把树的node通过中序遍历形成有序的list,再修改list内部Treenode的指针,前...原创 2020-04-28 16:20:26 · 86 阅读 · 0 评论 -
剑指offer系列-----item25 复制复杂链表
题干:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点:注意此处这个任意一个节点也是属于这个链表中的,这句话很重要!),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)思路:这道题关键就是有两点:1.绝对不能直接将引用指向原头节点:RandomListNode node = ...原创 2020-04-28 16:18:17 · 71 阅读 · 0 评论 -
剑指offer系列-----item24 找出二叉树中路径之和为目标值的所有路径
题干:输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)思路:思路有二:1.将所有的root到叶子节点的路径找出来,建成list,并用val的累加值做key,用后者list当val,再去对比与目标值到hashmap中去找相匹配的key。...原创 2020-04-28 11:11:35 · 303 阅读 · 0 评论 -
剑指offer系列-----item23 判断一个数组是否为二叉查找树的后序遍历
题干:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。思路:二叉搜索树的前序遍历一定是有序的,后序遍历的话,根节点在数组最后,前面的数组分为了比root大和比root小的部分,即root的左右子树。如果就这样递归下去,可以将数组中的每一个数统统遍历完成,那么说明结果为二叉搜索树的后序遍历,反之就不是,具...原创 2020-04-28 11:05:29 · 131 阅读 · 0 评论 -
剑指offer系列-----item22层次遍历二叉树
题干:一层一层的向下遍历二叉树,同一层的话再按照从左向右的顺序进行遍历即可。思路:别扯那么多,这就是二叉树的广度优先遍历:BFS。而广度优先遍历的精髓,或者说实现的原理就是队列,保证数据先进先出:先进左边节点、再进右边节点。从而输出就是先左边节点、再右边节点。(补一句:DFS的核心思想,或者底层原理则是栈,先进后出:先进右节点,再进左节点即可)具体代码如下:public ArrayLi...原创 2020-04-28 10:59:50 · 91 阅读 · 0 评论 -
剑指offer系列-----item21 压栈、出栈顺序判断
题干输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)思路题干中所言的所有的数字都不相等,其实是说明了根据入栈的顺序,出栈顺序是唯一的,判断结...原创 2020-04-27 20:17:30 · 137 阅读 · 0 评论 -
剑指offer系列-----item20 带min函数的stack栈
题干:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。思路:思路,一开始想着是压根不用栈,直接利用集合模拟栈这种数据结构的pop、push、top,最后再利用Collections工具类进行sort排序,输出第一个值即可。不过这样存在一个问题,时间复杂度太高了,Collection.sort的时间复杂度在O(n2)以上。那么改变思路,用两...原创 2020-04-27 15:58:59 · 88 阅读 · 0 评论 -
剑指offer-----item18 二叉树的镜像
题干输入一个二叉树,输出其二叉树的镜像。注:镜像为二叉树的所有左右节点交换。思路二叉树的镜像这种题目在面试中经常会被考到,划重点啦!!!这种题目经典的思路有两种。其一是传统递归;第二种就是非递归解法。方法一 传统递归递归法没有什么太好说的,既然是左右两个节点交换,那么就是所见即所得,利用递归实现交换就完事儿了。代码见下:public static void Mirror(TreeNo...原创 2020-04-26 20:59:47 · 122 阅读 · 0 评论 -
剑指offer-----item17 判断一棵树是不是另外一棵树的子结构
题干:判断一棵树是不是另一棵树的子结构思路:这道题值得注意的就是区分清楚什么是子树,什么是子结构。子树:是只要包含了一个结点,就得包含这个结点下的所有节点。子结构:包含了一个结点,可以只取左子树或者右子树,或者都不取。也就是说,单单一个节点都可以是一个子结构。具体代码如下:判断一棵树是不是另外一棵树的子结构:public class Solution { public ...原创 2020-04-25 22:32:49 · 86 阅读 · 0 评论 -
剑指offer系列-----item16 合并排序链表
题干:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。思路:这道题的方法有很多,首先大类分为两种:1.使用额外的空间;2.使用递归在原先链表中进行操作。1.使用额外的空间在这种思路中,可以两种额外空间的方式。第一种采用集合将两个链表中的val全部取出,然后隔离链表进行排序,之后再赋值给原先链表或者再新建一个链表。这种方法思路出气简单,新手一般会...原创 2020-04-23 20:28:43 · 145 阅读 · 0 评论 -
剑指offer系列-----item15 翻转链表
题干:将一个链表进行翻转。思路:这道题的思路明显,有两种典型思路解决。思路一:”假“翻转。所谓假翻转的意思就是,仅仅只翻转链表节点内部的数值,不翻转节点本身。具体而言,将链表内部的数值用集合”盛“出来,然后对这个链表进行翻转操作,最后再利用这个集合为链表重新赋值。值得一提的是,这种方法,链表节点之间的相互引用关系并未发生改变,变化的仅仅是节点内部的值。思路二:”真“翻转。所谓真翻转是针对...原创 2020-04-23 16:00:25 · 91 阅读 · 0 评论