
数据解构&算法
苍山如海z
从头越,苍山如海,残阳如血
展开
-
leetcode 142 环形链表
解题思路:这类链表题目一般都是使用双指针法解决的,例如寻找距离尾部第K个节点、寻找环入口、寻找公共尾部入口等。//环形链表相关import java.util.HashSet;class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; }}public class testg { //使用HashSet 解决原创 2020-09-22 09:49:02 · 134 阅读 · 0 评论 -
leetcode 200 岛屿数量
方法一:深度优先搜索我们可以将二维网格看成一个无向图,竖直或水平相邻的 11 之间有边相连。为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 11,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 11 都会被重新标记为 00。最终岛屿的数量就是我们进行深度优先搜索的次数。package com.zx.ds.sep20;//岛的数量public class testc { public static void dfs(char a[][]原创 2020-09-21 13:22:11 · 147 阅读 · 0 评论 -
动态规划算法 背包问题(01)
动态规划算法1)动态规 划(Dynamic Progamming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法2)动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若千个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。3)与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)4)动态规划可以通过填表的方式来逐步推进,得到最优解.背包问题:有一原创 2020-08-21 21:24:36 · 231 阅读 · 0 评论 -
KMP算法
字符串匹配问题:有一个字符串 str1= "BBC ABCDAB ABCDABCDABDE",和一个子串 str2="ABCDABD" 现在要判断 str1 是否含有 str2, 如果存在,就返回第一次出现的位置, 如果没有,则返回-1暴力匹配算法如果用暴力匹配的思路,并假设现在str1匹配到 i 位置,子串str2匹配到 j 位置,则有:如果当前字符匹配成功(即str1[i] == str2[j]),则i++,j++,继续匹配下一个字符 如果失配(即str1[i]! = str2[j].原创 2020-08-21 21:09:06 · 146 阅读 · 0 评论 -
分治算法(汉诺塔)
分治算法介绍分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 分治算法可以求解的一些经典问题 二分搜索 大整数乘法 棋盘覆盖 合并排序 快速排序 线性时间选择 最接近点对问题 循环赛日程表 汉诺塔分治算法的基本步骤分治法在每一层...原创 2020-08-21 11:00:09 · 697 阅读 · 0 评论 -
图(深度优先遍历&广度优先遍历)
图是一种数据结构,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称为边。 结点也可以称为顶点。图的表示方式图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。邻接矩阵邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是的row和col表示的是1....n个点。邻接表 邻接矩阵需要为每个顶点都分配n个边的空间,其实有很多边都是不存在,会造成空间的一定损失. 邻接表的实现只关心存在的边,不关心不存在的边。因此没有空间浪费,邻接表由数组+链表原创 2020-08-19 11:30:09 · 814 阅读 · 0 评论 -
平衡二叉树
给你一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在.上图BST 存在的问题分析:左子树全部为空,从形式上看,更像一个单链表. 插入速度没有影响 查询速度明显降低(因为需要依次比较), 不能发挥BST 的优势,因为每次还需要比较左子树,其查询速度比 单链表还慢 解决方案-平衡二叉树(AVL)平衡二叉树平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高。具.原创 2020-08-18 20:41:21 · 236 阅读 · 0 评论 -
二叉排序树
一个数列 (7, 3, 10, 12, 5, 1, 9),要求能够高效的完成对数据的查询和添加。使用数组数组未排序, 优点:直接在数组尾添加,速度快。 缺点:查找速度慢. 数组排序,优点:可以使用二分查找,查找速度快,缺点:为了保证数组有序,在添加新数据时,找到插入位置后,后面的数据需整体移动,速度慢。使用链式存储-链表 不管链表是否有序,查找速度都慢,添加数据速度比数组快,不需要数据整体移动。使用二叉排序树二叉排序树二叉排序树BST: (Binary Sort(Searc...原创 2020-08-18 14:03:49 · 125 阅读 · 0 评论 -
赫夫曼树
赫夫曼树给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。赫夫曼树相关概念路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1 结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值原创 2020-08-18 10:02:28 · 120 阅读 · 0 评论 -
堆排序
堆排序堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆 一般升序采用大顶堆,降序采用小顶堆堆排序的基本思想将待排序序列构造成一个大顶堆 此时,整个序列的最大值就是堆顶的根节点。 将其与末.原创 2020-08-18 09:45:39 · 138 阅读 · 0 评论 -
线索二叉树(中序)
将数列{1 ,3 ,6, 8 ,10 ,14}构建成一颗二叉树1)n个结点的二叉链表中含有n+1 [公式2n-(n-1)=n+1] 个空指针域。利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")2)这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种3)一个结点的前一个结点,称为前驱结点4)一个原创 2020-08-16 22:41:22 · 5093 阅读 · 0 评论 -
二叉树的顺序存储
从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组。package com.zx.ds.tree;//顺序存储二叉树class ArrBinaryTree{ private int arr[]; public ArrBinaryTree(int[] arr) { this.arr = arr; } //重载preOrder public void preOrder(){原创 2020-08-16 17:53:53 · 234 阅读 · 0 评论 -
二叉树
1.为什么需要树这种数据结构1)数组存储方式的分析优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。缺点:如果要检索具体某个值,或者插入值(按--定顺序)会整体移动,效率较低2)链式存储方式的分析优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可,删除效率也很好)。缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历)3)树存储方式的分析能提高数据存储,读取的效率,比如利用二叉排序树(Bi.原创 2020-08-16 16:05:45 · 88 阅读 · 0 评论 -
哈希表(数组+链表)
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中-一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。有一个公司,当有新的员工来报道时,要求将该员工的信息加入id,性别,年龄,名字,住址.),当输入该员工的id时,要求查找到该员工的所有信息1)不使用数据库,速度越快越好=>哈希表(散列)2)添加时,保证按照id从低到高插入[课后思考:如果id不是从低到高插入原创 2020-08-10 21:34:35 · 2078 阅读 · 0 评论 -
查找算法
1. 查找算法介绍在java中,我们常用的查找有四种:1)顺序(线性)查找 2)二分查找/折半查找 3)插值查找 4)斐波那契查找2. 线性查找算法package com.zx.ds.search;public class SeqSearch { public static int search(int a[],int findVal){ for(int i=0;i<a.length;i++){ if(a[i]==findVa原创 2020-08-10 18:24:23 · 153 阅读 · 0 评论 -
基数排序
基数排序(桶排序)介绍:1)基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucketsort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用2)基数排序法 是属于稳定性的排序,基数排序法的是效率高的稳定性排序法3)基数排序(Radix Sort)是桶排序的扩展4)基数排序是1887年赫尔曼●何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。基.原创 2020-08-10 15:08:01 · 324 阅读 · 0 评论 -
归并排序
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补"在一起,即分而治之)。归并排序基本思想合并相邻有序子序列:治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,原创 2020-08-10 14:02:07 · 112 阅读 · 0 评论 -
剑指 Offer JZ36 两个链表的第一个公共结点
题目描述输入两个链表,找出它们的第一个公共结点。/*public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}*/public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {原创 2020-08-07 15:29:15 · 173 阅读 · 0 评论 -
剑指 Offer JZ15 反转链表
题目描述输入一个链表,反转链表后,输出新链表的表头。迭代 使用头插法/*public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}*/public class Solution { public ListNode ReverseList(ListNode head) { ListNode原创 2020-08-07 14:22:43 · 339 阅读 · 0 评论 -
剑指 Offer JZ30 连续子数组的最大和
题目描述{6, -3, -2, 7, -15, 1, 2, 2},连续子数组的最大和为 8(从第 0 个开始,到第 3 个为止)。public class Solution { public int FindGreatestSumOfSubArray(int[] array) { int max=Integer.MIN_VALUE; for(int i=0;i<array.length;i++){ int temp=array[原创 2020-08-07 10:43:49 · 153 阅读 · 0 评论 -
剑指 Offer JZ63 数据流中的中位数
题目描述如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。import java.util.PriorityQueue;import java.util.Comparator;public class Solution { //PriorityQueue默认原创 2020-08-07 09:51:07 · 168 阅读 · 0 评论 -
快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外--部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列package com.zx.ds.ds0806;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;public原创 2020-08-06 14:36:40 · 112 阅读 · 0 评论 -
希尔排序
希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。希尔排序法基本思想希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一-组,算法便终止import java.util.Arrays;public class ShellSort { public static v原创 2020-07-31 22:21:56 · 110 阅读 · 0 评论 -
插入排序
插入式排序属于内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的。插入排序法思想:插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。package com.zx.ds.ds0731;//插入排原创 2020-07-31 21:44:13 · 154 阅读 · 0 评论 -
选择排序
选择排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的。选择排序思想:选择排序(select sorting)也是一种简单的排序方法。它的基本思想是:第一次从arr[0]~arr[n-1]中选取最小值,与arr[0]交换,第二次从arr[1]~arr[n-1]中选取最小值,与arr[1]交换,第三次从arr[2]~arr[n-1]中选取最小值,与arr[2]交换,第 i 次从arr[i-1]~arr[n-1]中选取最小值,与arr[i原创 2020-07-31 17:09:58 · 140 阅读 · 0 评论 -
冒泡排序
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。package com.zx.ds.ds0731;import java.util.Arrays;public class BubbleSort { public static void main(String[] args) { int array[] = {2原创 2020-07-31 12:05:29 · 126 阅读 · 0 评论 -
使用递归求解八皇后问题
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯.贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同--行、同一列或同--斜线上,问有多少种摆法(92)。八皇后问题算法思路分析1)第一个皇后先放第一行第一列 2)第二个皇后放在第二行第一列、然后判断是否OK,如果不 OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适(冲突的判断 判断是否在同一列 同一条斜线上) 3)继续第三个皇后,还是.原创 2020-07-30 22:23:47 · 488 阅读 · 0 评论 -
使用递归解决迷宫问题
使用二维数组来模拟迷宫,重点是setWay方法的理解//使用递归解决迷宫问题//1.使用二维数组模拟迷宫//2. setWay()public class MiGong { public static void printArray(int [][] a){ for(int row[]:a){ for(int col:row){ System.out.print(col+" ");原创 2020-07-30 19:17:54 · 474 阅读 · 0 评论 -
使用循环单链表解决约瑟夫问题
Josephu问题为:设编号为1,2,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。这里用一个不带头结点的循环链表来处理Josephu问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。以1,2,3,4,原创 2020-07-30 15:48:24 · 1491 阅读 · 0 评论