图解算法
文章平均质量分 52
各类算法详解
HankingHu
这个作者很懒,什么都没留下…
展开
-
笔试面试算法经典-打印n个数组中最大的topk
【题目】 有n个长度不一的数组,所有的数组都是有序的,请从大到小一次打印出这n个数组整体最大的 k 个数,如果 k大于n个数组中元素则将数组的元素全部打印。输入n行长度不等的二维数组可以表示n个长度不同的一维数组。例如:输入matrix={{1 , 2, 3 }, {4 , 5 }, {6 ,7 ,8 ,9 }, { 10 }}; k=4,输出:10,9,8,7。思路:建立一个大小为n的大根堆,原创 2017-04-16 17:15:40 · 3709 阅读 · 0 评论 -
笔试面试算法经典--最长连续序列
【题目】找出无序数组中的最长连续序列的长度:例如数组[ 1 , 23 , 2 , 300 , 3 , 9 ,4 , 5 , 90 ],最长连续序列为:1,2,3,4,5,因此返回长度为 5。解法 1(时间复杂度O( nlogn)空间复杂度O(1))思路:先对数组进行排序,然后从前向后遍历排序后的数组并且记录最长连续子数组长度。public int longestcontinueArrays(in原创 2017-04-19 19:00:17 · 16548 阅读 · 3 评论 -
笔试面试算法经典--最长回文子串
回文的定义正读和反读都相同的字符序列为“回文”,如“abba”、“abccba”是“回文”,“abcde”和“ababab”则不是“回文”。字符串的最长回文子串,是指一个字符串中包含的最长的回文子串。例如“1212134”的最长回文子串是“12121”。下面给出了三种求最长子串的方法。解法1(中心扩展法)时间复杂度O(n^2),空间复杂度为O(1)。中心扩展法的思路是,遍历到数组的某一个元素时,以这原创 2017-04-25 20:49:18 · 44721 阅读 · 10 评论 -
二叉树的遍历Java实现
使用Stack 遍历树而不递归。下面是使用堆栈遍历二叉树的算法。1)创建一个空栈S.2)以root身份初始化当前节点3)将当前节点推送到S,并设置current = current-> left,直到current为NULL4)如果current为NULL,堆栈不为空 a)从堆栈中弹出顶部元素。 b)打印弹出的元素,设置current = popped_item-> ri原创 2017-03-15 15:23:33 · 1148 阅读 · 0 评论 -
笔试面试算法经典--二叉树的镜像-递归与非递归实现(Java)
给出一棵二叉树,求它的镜像,如下图:右边是二叉树是左边二叉树的镜像。解法1(递归)思路1:如果当前节点为空,返回,否则交换该节点的左右节点,递归的对其左右节点进行交换处理。public static void mirrorTree(TreeNode root) { if(root==null) return; //交换该节点指向的左右节原创 2017-04-10 19:04:41 · 7968 阅读 · 3 评论 -
笔试面试算法经典--二叉树的子结构(Java)
题目描述 输入两棵二叉树A,B,判断B是不是A的子结构(空树不是任意一个树的子结构)。下图中:右边的二叉树是左边二叉树的子结构解法: 先序遍历 A树,如果当前节点与 B树的根节点相同,则判断 B 是不是 A的子树,判断 B是 A 的子树的也用递归:比较 B 的左子树 是否是 A 左子树的子结构,B 的右子树是否是 A的右子树的子结构。因此需要两个函数来进行,一个函数来进行先序遍历,一个来判断是否原创 2017-04-11 14:34:03 · 1827 阅读 · 0 评论 -
笔试面试算法经典--判断二叉树是否是平衡二叉树(Java)
平衡二叉树(Balanced Binary Tree)又被称为AVL树,且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。如下面的三棵树:只有中间才是平衡二叉树。解法: 思路1:从根节点开始,求出根的左右子树的高度,如果根的左右子树的高度差大于1,返回FALSE,否则递归的判断根的左子树和右子树是否满足条件。class TreeNode{原创 2017-04-11 22:40:54 · 4020 阅读 · 2 评论 -
笔试面试算法经典--二叉搜索树转有序的双向链表(Java)
题目: 输入一棵二叉搜索树,将该二叉搜索树转换为一个排序的双向链表。要求:不能创建任何新的结点,只能调整树中结点指针的指向。如下图:解法1(非递归): 思想:二叉搜索树的中序遍历是一个有序的数组,在中序遍历的时候,用 Pre 指针保存前一个节点,当访问到当前节点的时候,将 Pre 节点右指针,指向当前节点,当前节点的左指针指向 Pre。 这样中序遍历完二叉搜索树,就产生了一个双向链表。publi原创 2017-04-11 23:07:25 · 3101 阅读 · 0 评论 -
笔试面试算法经典--二叉树层次打印
【题目描述】 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。例如下面的树输出为: 12 5 18 2 9 15 19 17 16解法: 用队列来保存每层的节点,使用层次遍历,记录每层节点的个数,每层节点的个数其实是当前队列中没有加入任何子节点是队列的大小,然后将一行全部输出的同时将其子节点加入到队列。如上面图中,先原创 2017-04-12 22:49:11 · 2221 阅读 · 0 评论 -
Java 创建二叉树并遍历
public class BinaryTree { private Node root; /** * * 内部节点类 * @author yhh */ private class Node{ private Node left; private Node right;原创 2017-02-18 21:27:44 · 861 阅读 · 0 评论 -
二叉搜索树(篇1)判断数组是不是二叉搜索树后序遍历的结果
二叉搜索树(Binary Search Tree), 它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。上图中的二叉搜索树的后序遍历在数组中是:2 9 5 15 16 17 19 18 12思路: 数组中的最后一个节点是树的根节点,根节点原创 2017-03-18 10:05:17 · 1176 阅读 · 0 评论 -
二叉树的遍历(篇2)计算二叉树节点的个数
树的大小是树中存在的元素的数量。下面的树的大小是5。使用 Size()函数递归计算树的大小。它的工作原理如下: 树的大小=左子树的大小+ 1 +右子树的大小算法:size(树)1.如果树是空的,则返回02.否则 (a)递归获取左子树的大小,即调用 size(tree-> left-subtree) (a)递归获取右子树的大小,即调用原创 2017-03-15 11:22:41 · 3216 阅读 · 0 评论 -
二叉树的遍历(篇4)判断从根到叶节点的和是否等于某个给定的值
给定二叉树和一个数sum,如果从树的根开始到叶节点的值等于sum,则返回true。 如果没有找到这样的路径,则返回false。例如, 在上述树根到叶节点存在具有以下和。21 - > 10 - 8 - 3 23 - > 10 - 8 - 5 14 - > 10 - 2 - 2因此,返回的值应该只对数字21,23和14. true。对于任何其他数字,返回值应该为false。算法: 递归检查左原创 2017-03-15 16:12:23 · 1390 阅读 · 0 评论 -
二叉树的遍历(篇5)由中序和先序序列重建二叉树
让我们考虑下面的遍历:中序序列:DBEAFC 前序序列:ABDECF在Preorder序列中,最左侧的元素是树的根。所以我们知道’A’是给定序列的根。通过在Inorder序列中搜索’A’,我们可以发现’A’左侧的所有元素都在左子树中,右侧的元素在右子树中。所以我们现在知道下面的结构。 A / \ /原创 2017-03-15 16:58:32 · 771 阅读 · 0 评论 -
笔试面试算法经典--连续子数组的最大乘积及连续子数组的最大和(Java)
1. 子数组的最大和 输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。例如数组:arr[]={1, 2, 3, -2, 4, -3 } 最大子数组为 {1, 2, 3, -2, 4} 和为8。解法1(时间复杂度O(N * N)空间复杂度O(1)) 求出所有的子数组的和,比较选择出最大值。利用双重循环就可以遍历到所原创 2017-04-12 16:31:33 · 5569 阅读 · 0 评论 -
笔试面试算法经典--动态规划-最大子矩阵和(Java)
【题目】 给定一个矩阵 matrix,其中矩阵中的元素可以包含正数、负数、和0,返回子矩阵的最大累加和。例如,矩阵 matrix 为: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 拥有最大和的子矩阵为: 9 2 -4 1 -1 8 其和为15。原创 2017-04-12 17:36:20 · 7750 阅读 · 2 评论 -
经典算法--最大存水量问题
题目:给出一个数组代表围柱的高度,求能围柱的最大的水量,例如数组{ 5,2,3,2,4 },最大水量为5。如下图:黄色部分为围柱,绿色部分是能够围住的水,图中围柱的高度依次为 5,2,3,2,4最多能围住的水量是5。 思路:求出每个柱子上面原创 2017-04-29 20:09:17 · 9857 阅读 · 5 评论 -
笔试面试算法经典--最长公共子串(Longest Common SubString)
最长公共子串(Longest Common Substring): 是指两个字符串中最长连续相同的子串长度。例如:str1=“1AB2345CD”,str2=”12345EF”,则str1,str2的最长公共子串为2345。解法1如果 str1 的长度为 N,str2 的长度为 M,生成大小为 N*M 的 数组 dp , dp[i][j]表示 str1[0…i] 与 str2[0…j] 的最长公原创 2017-04-06 20:53:09 · 43142 阅读 · 8 评论 -
算法-动态规划 Dynamic Programming--从菜鸟到老鸟
前言最近在牛客网上做了几套公司的真题,发现有关动态规划(Dynamic Programming)算法的题目很多。相对于我来说,算法里面遇到的问题里面感觉最难的也就是动态规划(Dynamic Programming)算法了,于是花了好长时间,查找了相关的文献和资料准备彻底的理解动态规划(Dynamic Programming)算法。一是帮助自己总结知识点,二是也能够帮助他人更好的理解这个算法。后面的参原创 2017-07-15 22:58:29 · 466204 阅读 · 154 评论 -
堆排序HeapSort(Java)
堆排序堆排序思想:堆排序分为三个过程:①建堆:使得任一个节点的值大于左右孩子节点的元素因此堆顶的元素最大(大根堆)。②调整堆:删除掉堆顶元素后,还要保持堆的性质就要对堆进行调整。③堆排序:每次选择堆顶元素,并将堆顶元素删除,调整堆后,再重复操作直至堆为空。下面是这三种操作的具体过程:①建堆,建堆是不断调整堆的过程,从len/2处开始调整,一直到第一个节点,此处len是堆中元素的个数。建堆的过程是线性原创 2017-03-30 22:48:19 · 10219 阅读 · 3 评论 -
二叉树的遍历(Java)
树可以以不同的方式遍历。以下是遍历树的常用方法。深度优先遍历:(a)中序遍历(左、根、右):4 2 5 1 3 (b)先序遍历(根、左、右):1 2 4 5 3 (c)后序遍历(左、右、根) :4 5 2 3 1广度优先或水平顺序遍历: 1 2 3 4 5 先序遍历 算法Inorder(树) 1.遍历左子树,即调用Inorder(left-subtree) 2.访问根节点。原创 2017-03-15 11:09:59 · 776 阅读 · 0 评论 -
归并排序MergeSort(Java)
归并排序思想:先将数组中的每两个进行合并并且在合并的过程中进行排序,然后每四个进行合并。一直到数组合并完成。 例如上图中:要对数组中的元素:80、30、60、20、10、60、50、70进行排序,先把数组分成8组先分别对这八组进行合并排序,(30,80),(20,60),(10,60),(50,70)这四组组内已经排好序。然后继续排序(20,30,60,80)(10,50,60,70)最后对这两组原创 2017-03-30 22:01:28 · 3827 阅读 · 0 评论 -
笔试面试算法经典--全排列算法-递归&字典序实现(Java)
全排列算法-递归&字典序实现全排列: 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。 例如: 1 、2 、3三个元素的全排列为:{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}。解法1(递归) 如下图:要对1、2、3、4进行排序,第一个位置上的元素有四原创 2017-04-01 09:48:42 · 39842 阅读 · 15 评论 -
笔试面试算法经典--矩阵的最短路径和(Java)
题目 给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有路径中最小的路径和。 例子: 给定m如下: 1 3 5 9 8 1 3 4 5 0 6 1 8 8 4 0 路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12。解法1思路:使用动态规划,定义 dp[M][N] , M ,原创 2017-04-07 17:11:17 · 16960 阅读 · 0 评论 -
笔试面试算法经典-找到数组中出现次数大于N/k的数(Java)
【题目】 给定一个整型数组arr,再给定一个整数k,打印所有出现次数大于 N/K 的数。如果没有这样的数,打印提示信息。 【要求】 时间复杂度为O(N*K),额外空间复杂度为O(K)。【思路】 每次从数组中删除 K 个不同的数,如果某个数的次数大于 N/K ,这个数最后肯定会剩下来,数学证明:假设 X 的次数为 (N/k+1) > N/K ,如果每次删除 k个不同的数最后数组里面剩余的原创 2017-04-08 22:46:07 · 6345 阅读 · 4 评论 -
笔试面试算法经典--打印数组中相加和为给定值的二元组及三元组(Java)
【题目】给定一个递增的数组,要求打印数组中和为给定值的二元组,例如: arr[]={-8, -4, -1, 0, 1, 3, 4, 5, 6, 7, 9} , k=10,打印结果为: 1——9 3——7 4——61.打印二元组解法1(时间复杂度 O(N * N)空间复杂度 O(1)) 思路:利用双重循环遍历数组中的所有二元组,如果二元组相加的值为 k 打印。public static原创 2017-04-13 21:52:38 · 1785 阅读 · 0 评论 -
笔试面试算法经典-未排序正整数数组中累加和为给定值的子数组
【题目】 给定一个数组 arr,该数组无序,但每个数均为正数,再给定一个正数 k 。求 arr 的所有子数组中所有元素相加为k的最长子数组长度。例如,arr=[1,2,1,1,1],k=3。累加和为3的子数组为[1,2] ,[2,3], [1,1,1]。解法1(时间复杂度O(N)空间复杂度O(1))思路:left,right来指向数组中的某一个区间,sum用来保存left和right区间中的值,由原创 2017-04-13 23:15:29 · 1383 阅读 · 0 评论 -
笔试面试算法经典--数组partition调整使数组的左部分单调有序
【题目】 给定一个有序数组arr,调整使得数组的左部分无重复元素且有序,右边部分不要求。如数组arr[]={1,2,2,2,3,3,4,5,6,9,9} ;调整过后可以为:[1, 2, 3, 4, 5, 6, 9, 2, 3, 2, 9] 。思路:使用标记 u 其中arr[0…u] 表示已经处理过的没有重复元素且有序的区间,从arr[u+1…i-1]表示有重复元素的部分。则算法主要分为下面两部分。原创 2017-04-14 16:06:42 · 984 阅读 · 0 评论 -
Stack(篇2)设计一个栈能在O(1)的时间和O(1)的空间getMin()
在上一篇文章中实现了 使用O(1)时间和O(n)的额外空间的方法getMin()。在本文中,讨论了一种支持O(1)额外空间的最新方法。 我们定义一个变量minEle,它存储堆栈中的当前最小元素。现在的问题是如何处理最小元素被删除的情况。为了处理这个,我们将“2x-minEle”推入堆栈而不是x,以便可以使用当前的minEle检索先前的最小元素,并将其值存储在堆栈中。以下是工作的详细步骤和说明。P原创 2017-03-23 22:08:42 · 1871 阅读 · 0 评论 -
剑指offer-求数组中最小的k个数
题目描述 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。解法1(冒泡排序)冒泡排序每循环一次能够选出一个最小的数,题目要求选出最小的k的数,因此时间复杂度为O(k*N)。import java.util.ArrayList; public class Solution { public ArrayList<Inte原创 2017-03-25 22:22:20 · 924 阅读 · 0 评论 -
动态规划(篇2)最长递增子序列(LIS)
最长增加子序列(LIS)问题是找到给定序列的最长子序列的长度,使得子序列的所有元素以增加的顺序排序。例如,{10,22,9,33,21,50,41,60,80 }的LIS的长度为6,LIS为 {10,22,33,50,60,80}。最优子结构: 令arr [0..n-1]是输入数组,L(i)是以 i 结束的LIS的长度,使得arr [i]是LIS的最后一个元素。 然后,L(i)可以递归地写为:原创 2017-03-14 10:09:40 · 15260 阅读 · 0 评论 -
Levenshtein distance最小编辑距离算法实现
动态编程| (编辑距离) 给定两个字符串str1和str2以及可以对str1执行的操作。找出将“str1”转换为“str2”所需的最小编辑次数(操作)。插入删除代替所有上述操作具有相等的成本。例子:输入:str1 =“geek”,str2 =“gesek” 输出:1 我们可以通过插入一个's'将str1转换为s原创 2017-03-13 22:10:03 · 4110 阅读 · 3 评论 -
动态规划(篇3)最长公共子序列(LCS)
LCS问题陈述: 给定两个序列,找出它们中存在的最长子序列的长度。子序列是以相同的相对顺序出现但不一定是连续的序列。例如,“abc”,“abg”,“bdf”,“aeg”,“acefg”,…等是“abcdefg”的子序列。因此,长度为n的串具有2 ^ n个不同的可能子序列。 示例: 用于输入序列的LCS“ABCDGH”和“AEDFHR”是长度为3的“ADH”。 用于输入序列的LCS“AGGT原创 2017-03-14 15:37:22 · 2862 阅读 · 0 评论 -
动态规划(篇1)重叠子问题
动态规划是一种算法范例,通过将其分解为子问题来解决给定的复杂问题,并存储子问题的结果,以避免再次计算相同的结果。 以下是一个问题的两个主要属性,表明给定的问题可以使用动态规划来解决。 在这篇文章中,我们将详细讨论第一个属性(重叠子问题)。动态规划的第二个属性在下一篇文章即动态规划篇2中讨论。1)重叠子问题 2)最佳子结构 1)最佳子结构像分治法一样,动态规划包含了对子问题的解决。动态规划原创 2017-03-14 09:23:55 · 6637 阅读 · 1 评论 -
快速排序QuickSort(Java)
快速排序思想 如上图:每趟快速排序开始时,设置一个key,key=array[low],然后由high向左,找到小于key的值,复制到low位置,然后再由low向右找到大于key的值,复制到high位置,直到low=high结束, 将key的复制到low位置。 上图中第一轮划分后找到32的位置,然后递归的对32左边和右边的进行排序。代码:package Sort;import原创 2017-03-31 09:43:45 · 17402 阅读 · 7 评论 -
Stack(篇3)设计一个栈能够在O(1)的时间内getMin
问题:设计一个数据结构SpecialStack,支持所有的栈操作,如push(),pop(),isEmpty(),isFull()和一个附加的操作getMin()它应该从SpecialStack返回最小元素。SpecialStack的所有这些操作必须是O(1)。要实现SpecialStack,你应该只使用标准的Stack数据结构,没有其他数据结构,如数组,列表,等等。 例:请考虑以下Special原创 2017-03-23 22:17:00 · 1147 阅读 · 0 评论 -
Stack(篇1)计算全排列大于等于其的自然数
有一些自然数,其所有排列大于或等于该数字,例如。123,其所有置换(123,231,321)都大于或等于123。 给定自然数n,任务是计数从1到n的所有这样的数。 例子:输入:N = 15 输出:14 1,2,3,4,5,6,7,8,9,11,12,13,14,15是其所有的数字排列比数大于本身。因此,输出14. 输入:n = 100. 输出:54解法1(暴力解法) 从1到n计算原创 2017-03-20 17:29:29 · 1023 阅读 · 0 评论 -
Stack(4)判断数组是不是二叉搜索树的前序遍历(递归及非递归实现)
给定一个数组,如果给定的数组是二进制搜索树的先序遍历结果,则返回true,否则返回false。时间复杂度为O(n)。 例子:输入: pre[] = {2, 4, 3}输出: true下面是上面数组对应的二叉搜索树 2 \ 4 / 3输入: pre[] = {2, 4, 1}Output: false上面的数组不对应任何二叉搜索树.输入:原创 2017-03-24 16:40:00 · 1220 阅读 · 0 评论 -
Stack(5)对栈排序不用循环空间复杂度O(1)
对栈stack排序,不能使用循环while,for等,只能使用Stack的以下方法(Java版本)isEmpty():判断堆栈是否为空。push(S):将新元素添加到堆栈。pop(S):从堆栈中删除顶层元素。peek(S):返回顶元素的值。例输入:-3 <---顶部 14 18 -5 30 输出:30 <---顶部原创 2017-03-24 20:54:37 · 1696 阅读 · 0 评论 -
剑指offer-丑数(Java)
题目描述 把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。思路: 使用一个数组将之前已经求出来的丑数保存起来,然后依次用2,3,5乘上数组中已经求出来的丑数,选出其中最小的一个保存到数组中。假设数组中存的最大丑数是Max,那么只要求出2,3,5乘以数组中的某一个数刚好原创 2017-03-27 22:11:43 · 2941 阅读 · 0 评论