数据结构与算法
ASN_forever
这个作者很懒,什么都没留下…
展开
-
冒泡排序及java实现
冒泡排序思想如果是升序的话,就是先两两比较得到最大的数并放在末尾,然后从头循环比较得到第二大的数放到倒数第二个位置,依次循环执行,直到只剩下第一个数和第二个数进行依次比较后,便得到有序数组。算法复杂度如果数组中有N个数据项,那么第一次排序找到最大的数需要比较N-1次,第二次找到第二大的数需要比较N-2次,依次类推,得到总共需要比较:(N-1)+(N-2)+...+1=N*(N-1)/2。而对于是否...原创 2018-07-01 16:56:15 · 201 阅读 · 0 评论 -
LeetCode303题:区域和检索——数组不可变
常规思路:这道题说白了就是要你写一个函数,这个函数有两个int型的形参i和j,分别表示数组的两个下标,然后需要返回这两个下标及其之间的所有数的和。如果只考虑单次调用的需求的话,直接从i到j累加就完了。但说明中提到,函数会被多次调用。那么如果每次调用都从i到j累加一遍的话,之前累加的结果就浪费了,相同的i和j每次都会做重复的累加,效率就会很低了。因此需要换一种思路。非常规解法:初始化数组...原创 2018-12-12 22:18:43 · 298 阅读 · 0 评论 -
LeetCode102:二叉树的层次遍历
思路:用一个队列和列表来实现。主要是两层循环,外层循环用来获取队列大小size以及初始化一个列表list(用来存储当前层的节点),内层循环用来依次从队列中从左到右的取出当前层节点放到list中,并将当前节点的左右子结点插入到队尾。每次从队列中取出一个节点的时候都要对size进行自减操作,直到当size==0时,也就是当前层所有的节点都从队列中取出后,再重新开始外层循环,计算下一层的结点数si...原创 2018-12-07 09:51:23 · 197 阅读 · 0 评论 -
全排列的java递归实现
思路:全排列,对于数组来说,就是某一个下标处可以放整个数组所有的元素。因此每个位置的元素都用其后的各个元素依次与其进行互换,直到需要互换的是最后一个元素时,打印出来的结果就是某一种全排列,然后返回到上一个元素。返回时要注意需要再互换一次回复到原来的状态。后来发现,原来以前写过全排列:https://blog.csdn.net/ASN_forever/article/details/847834...原创 2018-12-14 18:11:44 · 814 阅读 · 0 评论 -
LeetCode438题:找到字符串中所有字母异位词
原始思路1: 获取p串的全排列,与s暴力对比但这种方法时间复杂度太高,主要是因为全排列的复杂度太高,如果p字符串长度为n的话,那么全排列复杂度为O(n!)。严重超时。public class Test { Set<String> set = new HashSet<String>(); public static void main(String[] ...原创 2018-12-15 13:31:30 · 589 阅读 · 0 评论 -
LeetCode204题:计数质数
这道题真的是解法很多,但满足时间复杂度的还不太容易想。解法一:暴力法外层循环从2到n,内层循环从2到ni,然后ni取模内层循环的值,判断是否为质数。复杂度O(n2),舍弃。解法二:根据之前的质数求思路:一个数如果与比它小的所有的质数取模后结果都不为0时,那么此数也是质数。所以,从2开始遍历到n时,每遇到一个质数就将其放到ArrayList中(用ArrayList而不用trees...原创 2018-12-10 23:36:22 · 408 阅读 · 0 评论 -
LeetCode105题:从前序和中序遍历序列构造二叉树
思路: 首先要清楚二叉树的前序遍历和中序遍历的过程。所谓的前序遍历,其遍历顺序为:当前节点-->左子树-->右子树;而中序遍历的遍历顺序为:左子树-->当前节点-->右子树。因此,中序遍历序列中某一节点的左右两侧则分别为其左右子树。这样思路就出来了,先在前序遍历序列中设定当前节点,然后在中序遍历序列中遍历找到当前节点,然后对其左右子树(即左右两侧的局部序列)分别进行...原创 2018-12-21 21:09:42 · 521 阅读 · 0 评论 -
LeetCode106题:从中序与后序遍历序列构造二叉树
思路: 本题的思路与LeetCode105题:从前序与中序遍历序列构造二叉树的思路非常类似。只不过这里要根据后序遍历序列遍历当前节点而已。class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { return helpBuild(inorder,postorder,...原创 2018-12-21 22:23:49 · 285 阅读 · 0 评论 -
LeetCode235题:二叉搜索树的最近公共祖先
这道题要充分利用二叉搜索树的性质,即比某一节点大的数全在其右侧,比其小的数全在其左侧。思路:知道了二叉搜索树的性质后,根据其性质可知,如果p和q在节点temp的两侧的话,也就是当(p.val - temp.val)*(q.val - temp.val)<=0时(包含“=”号,因为“一个节点也可以是它自己的祖先”),则当前节点temp就是它们的最近公共祖先。否则说明p和q都在tem...原创 2018-12-11 16:37:46 · 652 阅读 · 0 评论 -
LeetCode783题:二叉搜索树结点最小距离
思路一:中序遍历然后循环比较这道题其实跟第530题是一样的。都是求二叉搜索树的任意两个结点之差的最小值。这时候关键要清楚二叉搜索树的原理,即当前节点大于其左子树小于其右子树。同时考虑到二叉搜索树的中序遍历实际上一个正序排序的过程,因此可以先对二叉搜索树中序遍历并保存到list中,然后循环比较前后两个元素之差找到最小差即可。public int minDiffInBST(TreeNod...原创 2018-12-22 17:18:18 · 353 阅读 · 0 评论 -
LeetCode938:二叉搜索树的范围和
思路一:中序遍历后遍历求和只要是关于二叉搜索树的问题,首先要想到二叉搜索树的特征以及中序遍历的特征。此题中的L和R指的是中序遍历排序后的前后两个结点。因此,要求L和R之间所有结点的值的和,就可以先中序遍历得到排序后的数组,然后遍历数组求和即可。 public int rangeSumBST(TreeNode root, int L, int R) { Array...原创 2018-12-22 21:35:39 · 652 阅读 · 0 评论 -
LeetCode257题:二叉树的所有路径
思路: 关键点是路径的定义,即根结点到叶子节点。而判断是否为叶子节点只需要判断其左右子结点是否都为空即可。递归实现,如果当前节点不为空就将其值val加入到stringbuffer中,并在此条件下判断它是否为叶子节点(即左右子节点都为空),如果是则将stringbuffer添加到list中,否则,如果有左子节点,则递归到左子节点,如果有右子节点,则递归到右子节点。需要注意的是,递归的时候...原创 2018-12-12 10:10:50 · 189 阅读 · 0 评论 -
LeetCode263:丑数
解法一:循环法根据定义,丑数是质因数只包含2,3,5的数。意思如果一个正整数m存在i,j,k(i,j,k都是非负整数)使得m = 2*i+3*j+5*k,那么m就是一个丑数。所以只要依次尽可能的取模2,3,5,最后的余数如果是1,那么就是丑数了。(这个很简单,稍微想一下应该就知道原因了)public boolean isUgly(int num) { if(num =...原创 2018-12-12 13:22:00 · 285 阅读 · 0 评论 -
LeetCode198题:打家劫舍
思路:每个房子都有两种结果,要么被抢要么不被抢。因此要计算从1号到i号房子最多能抢多少现金,可以用下面的公式表示:rob(i) = Max("i被抢","i不被抢")。因此,对于i号房子,需要同时分析被抢和不被抢两种情况,比较获取最大值即可。i被抢如果第i个房子被抢,因为相邻的房子不能同时被抢,所以i-1不能被抢,能被抢的只能是i-2及之前的房子,因此,当第i个房子被抢时,可以...原创 2018-12-23 23:19:46 · 316 阅读 · 0 评论 -
LeetCode746题:使用最小花费爬楼梯
思路: 这题与LeetCode198题“打家劫舍”属于相同题型,都涉及到动态规划的思想。对于第i阶楼梯来说,有两种情况,要么走第i阶楼梯,要么直接跨过第i阶楼梯。而最终要求从1阶登过i阶的最小总花费cost(i)就可以用下面的公式表示:cost(i) = min(“走i阶时的最小总花费”,“跨过i阶时的最小总花费”) 接下来对这两种情况进行讨论。1)走i阶时的最小总花费...原创 2018-12-24 10:35:07 · 444 阅读 · 0 评论 -
LeetCode64题:最小路径和
思路: 题目要求的是从左上角即[0,0]位置开始,到右下角即[m-1,n-1]位置为止的最小路径和。倒过来思考的话,对于右下角[m-1,n-1]来说,它的上一步只有两个位置即[m-2,n-1]和[m-1,n-2],因此问题就可以转化为求从[0,0]到这两个位置的路径和的较小值,即状态转移公式为:min ( arr[m-1][n-1] ) = min ( arr[m-1][n-1]+min(...原创 2018-12-25 15:00:05 · 554 阅读 · 0 评论 -
LeetCode63题:不同路径2
思路:这道题与LeetCode62题几乎完全相同,只是在62题的基础上增加了“障碍”限制。因为只能向右和向下移动,那么容易想到,如果某一处[i,j]有障碍,那么它右侧的[i,j+1]位置只能经过[i-1,j+1]到达。因此[i,j+1]的值用[i-1,j+1]代替即可。如果一个位置[i,j]的上边和左边都是障碍的话,那么这个位置肯定不会被任何一个路径经过,因此可以认为是"隐形"障碍(第一行...原创 2019-01-04 23:57:14 · 349 阅读 · 0 评论 -
LeetCode378题:有序矩阵中第k小的元素
思路:首先分析已知条件,即数组是每行从左到右递增,每列从上到下递增的(非严格递增)。要找到第k小的元素,那么最笨的方法就是将数组所有元素升序排序后,取第k个元素;或者是用优先级队列的思想,始终维持已遍历元素中的k个最小元素,直到遍历结束,取队列的最后一个元素;或者用小顶堆的数据结构,遍历数组并构建堆,构建完成后,找到第k小的元素。解法一:排序(最笨的) public int kt...原创 2018-12-25 23:23:03 · 2426 阅读 · 0 评论 -
美团后台开发笔试
import java.util.Scanner;public class Main { static int count = 0; public static void main(String[] args) { Scanner s1 = new Scanner(System.in); String[] line1 = s1.nextLine().split(" "); ...原创 2018-09-06 21:55:11 · 747 阅读 · 0 评论 -
N级台阶,一次上1级或2级或3级或M级,总共有多少种走法
思路先分析最简单的,也就是每次要不上1级,要么上2级。这个问题需要反过来思考才能比较容易的找到规律。总共有N级台阶,因为每次要么上1级要么上2级,因此对于第N级台阶来说,它的前一步要么是在N-1级处要么是在N-2级处。在N-1级处时上1级到N级台阶,在N-2级处时上2级到N级台阶。因此,可以用公式表示为f(n)=f(n-1)+f(n-2),其中f(n)表示从第一级开始到第n级有多少种走法。...原创 2018-09-07 21:05:40 · 23247 阅读 · 3 评论 -
商汤科技2018笔试
原创 2018-09-07 20:21:10 · 3329 阅读 · 0 评论 -
选择排序及java实现
选择排序思想选择排序就是从数组的最左边开始,每次从剩余的元素中选出最小的元素与当前元素对调位置。下一次从左数第二个开始,选出其右边的最小的数并与之对换位置,依次找到每一个位置上应该填的最小值。与冒泡排序的区别选择排序是改进的冒泡排序,冒泡排序没比较一次就有可能需要交换一次位置,而选择排序只有找到剩余元素中的最小值时才会对调位置。因此选择排序的交换次数从O(N^2)减少到了O(N)。但是比较次数仍为...原创 2018-07-01 18:57:04 · 133 阅读 · 0 评论 -
插入排序及java实现
插入排序思想插入排序采用的是一种局部有序的思想,所谓局部有序,就是说在数组左边某几个元素之间是有序的,但是未排序的元素可能会在接下来的排序中打乱他们的局部排序。而冒泡排序和选择排序不存在局部有序,因为它们每次都是选择的都是剩余中最大的元素。插入排序的过程是从第二个元素开始的,因为第一个元素只有自己,也属于局部有序。从第二个元素开始,每个元素都与其左边的挨个比较,如果比左边的小,那么将左边的元素后移...原创 2018-07-01 21:16:49 · 128 阅读 · 0 评论 -
队列及java实现
队列队列与栈不同,栈是一种先进后出的数据结构,因此对于入栈push和出栈pop操作来说可以使用同一个指针。而队列是先进先出的,对于插入和删除操作来说,插入(进)的位置在队尾,删除(出)的位置在队首,因此需要队首(front)和队尾(rear)两个指针。循环队列对于用数组实现的队列来说,最初的实现方式是插入操作从数组的0下标位置开始,每次插入下标+1,删除也从0下标开始依次从队首往队尾的方向删除。并...原创 2018-07-02 15:49:36 · 266 阅读 · 0 评论 -
优先级队列及用java数组实现
优先级队列所谓优先级队列,其实和普通队列一样,也有一个队首一个队尾,并且也是从队首删除数据。只不过是其中的数据项是按照升序或降序的方式存储在队列中的,如果是升序优先级队列,则具有最小关键字值的数据项拥有最高优先级并放在队首位置。...原创 2018-07-03 10:43:03 · 691 阅读 · 2 评论 -
单链表及其java实现
链表链表是除数组之外应用最多的一种数据存储结构。它很多时候可以取代数组作为其他存储结构的基础,例如栈和队列。链表有很多种,包括单链表、双端链表、有序链表、双向链表和有迭代器的链表。数组的缺点无序数组中搜索效率低,有序数组中插入效率低,不管是有序数组还是无序数组的删除效率都很低。插入新节点java实现插入和删除操作的对象都是从表头开始public class LinkListApp { publi...原创 2018-07-03 14:58:42 · 227 阅读 · 0 评论 -
双端链表
双端链表双端链表与单链表的区别是在表头多了一个last属性,用来保存表尾节点的引用。如果链表中只有一个节点,那么first和last都指向它,如果没有链节点则两者都为null。双端链表能够实现在表头和表尾进行插入和删除操作,这也是它的主要特点。而单链表要想实现在表尾进行插入和删除,需要从表头开始遍历得到表尾的引用后才能进行,效率低。...原创 2018-07-03 16:13:20 · 323 阅读 · 0 评论 -
双向链表
双向链表双向链表不同于双端链表。双向链表的目的是解决普通链表中只能向下遍历的缺陷,为此双向链表为每个节点增加了一个previous属性,用于保存上一个节点的引用。双向链表不一定是双端链表,也就是说表头不一定要保存表尾的引用。...原创 2018-07-03 16:50:38 · 139 阅读 · 0 评论 -
深度优先搜索算法及java实现——针对无向无权图
图是一种比树更宽泛和复杂的数据结构,树只是图的一种特殊形式。图有很多种划分方式,针对不同的划分方式可以分为连通图/非连通图、有向图/无向图、带权图/非带权图等。图与树不同,树一般都有固定的结构,如二叉树,一个节点最多有两个子节点,因此可以通过在节点对象中添加两个属性用来存储子节点的引用(类似于边),以此方式实现二叉树。或者是用数组的方式实现数(也就是堆结构)。但是对于图来说,它的邻接顶点的个数是不...原创 2018-07-11 00:28:17 · 2094 阅读 · 0 评论 -
归并排序、希尔排序、快速排序的基本思想过程及java实现
参考博文:https://blog.csdn.net/qq_35434690/article/details/76187262归并排序归并排序是根据将两个有序数组合并成一个有序数组的思想发展而来,如果两个数组有序,那么只需要依次比较两个数组中的每个数,小的数放进空数组中,并原数组游标向前移动一位进行下一次比较,直到当一个数组的游标到达数组尾部(也就是这个数组被比较完了)时,直接将另一个数组...原创 2018-07-04 15:02:15 · 508 阅读 · 0 评论 -
不带权图:基于深度优先搜索实现的最小生成树——java实现
深度优先搜索参考:https://blog.csdn.net/ASN_forever/article/details/80993836最小生成树用最少数量的边来实现图中各顶点之间的连通,也就是用最少数量的边实现连通图,则这些边就组成了一个最小生成树。同一个图,通常有很多个最小生成树。最小生成树边的数量永远都比顶点的数量少1。下面是基于深度优先搜索实现的最小生成树java代码/** * 在使用邻接...原创 2018-07-11 13:45:11 · 765 阅读 · 0 评论 -
用warshall算法求图的传递闭包矩阵
传递闭包传递闭包的意思是说,如果顶点A能到达顶点B,并且顶点B能到达顶点C,那么顶点A一定能到达顶点C。因此可以通过修改原始邻接矩阵得到传递闭包矩阵,使用的方法就是warshall方法。原始邻接矩阵只表示哪些顶点是邻接顶点,而传递闭包矩阵表达的是每个顶点可以到达哪些顶点。warshall算法的关键代码//生成闭包矩阵 public void getClosureMatrix(){ for(i...原创 2018-07-11 16:19:38 · 3971 阅读 · 1 评论 -
广度优先搜索算法及java实现——针对无向无权图
深度优先搜索及java实现:https://blog.csdn.net/ASN_forever/article/details/80993836广度优先搜索广度优先搜索是除深度优先搜索之外,对图进行搜索时采用的另一种基本算法。广度优先搜索算法的思想广度优先搜索使用队列进行操作。首先选定一个顶点作为起始顶点,将其放到队尾(此时也是队首)作为当前顶点,并做标记表示已读,然后寻找当前顶点(队首位置的顶点...原创 2018-07-13 14:04:39 · 1343 阅读 · 2 评论 -
贝壳找房2018算法笔试
第一题import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Scanner;import java.util.Set;public class Main { public static void ...原创 2018-08-19 00:32:13 · 3656 阅读 · 2 评论 -
数据结构——树
树树是树形结构的简称。它是一种重要的非线性数据结构。树或者是一颗空树,即不含有任何结点,或者是一颗非空树,即至少含有一个结点。在一颗非空树中,它有且仅有一个称作“根”的结点,其余所有结点被分为m棵互不相交的子树,每棵子树的根结点是整个树根结点的后继,而整个树根结点又是所有子树根结点的前驱。结点的度和树的度每个结点具有的子树数或者说后继结点数被定义为该结点的度。而树的度指的是树中所有结点...原创 2018-08-27 13:53:36 · 168 阅读 · 0 评论 -
二分查找的java实现以及平均查找长度
首先要明白,二分查找是建立在有序数组的基础上的。二分查找主要有递归和非递归两种算法实现/** * 二分查找的递归和非递归实现 * * @author ht * */public class BinarySearch { public static void main(String[] args) { Arr a = new Arr(10); a.addNum(1)...原创 2018-08-28 10:21:45 · 4398 阅读 · 4 评论 -
堆排序
参考链接:https://www.cnblogs.com/chengxiao/p/6129630.html转载 2018-08-29 07:51:29 · 114 阅读 · 0 评论 -
2018携程笔试
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String[] num = sc.nextLine().split(" "); int x1 = Integer....原创 2018-09-04 22:04:23 · 815 阅读 · 0 评论 -
LeetCode96题:不同的二叉搜索树
思路:一般来说,只要涉及到二叉树或二叉搜索树的,基本都要用到根结点和递归的思想。对于本题来说,假设要求的结果为f(n),那么开始分析:由1到n节点组成的二叉搜索树的根结点总共有n种取值情况,即1,2...n分别作为根结点,当1作为根结点时,其左子树为空记为f(0),右子树为2到n总共n-1个节点组成的二叉搜索树,且这n-1个节点总共有f(n-1)种组成情况,因此,以1为根结点时,总共有f(...原创 2019-01-07 16:55:13 · 262 阅读 · 0 评论