
算法
许文杰
Java程序开发
展开
-
分布式自增ID算法snowflake(雪花算法)
前言在分布式系统中,有时存在需要使用全局唯一ID的场景。此时为了防止ID冲突,可以使用36位的UUID。但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。因此我们希望能使用一种简单点的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake(雪花算法)解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。snowflake结构首位未使用,接下来的41位原创 2020-07-05 16:50:25 · 1067 阅读 · 0 评论 -
剑指offer第二版面试题36:二叉搜索树与双向链表(java)
题目描述: 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点指针的指向。比如如下图中的二叉搜索树,则输出转换之后的排序双向链表为: 分析:在二叉树中,每个结点都有两个指向子节点的指针。在双向链表中,每个结点也有两个指针,他们分别指向前一个结点和后一个结点。由于这两种结点的结构相似,同时二叉搜索树也是一种排序的数据结构,因此在理论上有...原创 2018-06-04 09:33:32 · 1732 阅读 · 2 评论 -
剑指offer第二版面试题35:复杂链表的复制(java)
题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)分析: 思路1: 先复制原始链表的结点 在元素链表的头结点开始找每个结点的random。每次都要从头开始找,然后连接起来,所以时间复杂度是o(n*n) 思路2:...原创 2018-05-25 18:50:05 · 663 阅读 · 0 评论 -
剑指offer第二版面试题34:二叉树中和为某一值的路径(java)
题目描述: 输入一颗二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。路径定义为从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。分析: 对于树的遍历一般就是深度遍历和广度遍历下四种中的一种,从根节点往下找到叶节点形成一条路径,若是和为给定的值这个路径便是需要找的路径,从根节点到叶节点边访问边相加判断可以采用先序遍历。 (1)若根节点的值大于给定的值或者根节点为空,...原创 2018-05-25 14:57:23 · 959 阅读 · 0 评论 -
剑指offer第二版面试题33:二叉搜索树的后序遍历序列(java)
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是返回true,否则返回false。假设输入的数组的任意两个数字互不相同。分析: 已知条件:后序序列最后一个值为root;二叉搜索树左子树值都比root小,右子树值都比root大。 1、确定root; 2、遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树; 3...原创 2018-05-25 14:23:53 · 543 阅读 · 0 评论 -
剑指offer第二版面试题32:从上到下打印二叉树(java)
题目一描述: 从上往下打印二叉树的每个节点,同一层的节点按照从左到右的顺序打印。例如输入下图的二叉树,则一次打印出8,6,10,5,7,9,11。 分析: 这道题实质上考察的就是树的遍历算法,只是这种遍历不是我们熟悉的前序、中序或者后序遍历。由于我们不太熟悉这种按层遍历的方法,可能一下也想不清楚遍历的过程。 因为按层打印的顺序决定应该先打印的根节点,所以我们从树的根节点开始分析。为了接...原创 2018-05-25 11:52:20 · 3378 阅读 · 0 评论 -
剑指offer第二版面试题31:栈的压入、弹出序列(java)
题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压栈序列,序列,4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。分析: 解决这个问题很直观的想法就是建立一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的...原创 2018-05-07 22:45:56 · 500 阅读 · 0 评论 -
剑指offer第二版面试题30:包含min函数的栈(java)
题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1).分析: 看到这个问题,我们的第一反应可能是每次压入一个新元素进栈时,将栈里的所有元素排序,让最小的元素位于栈顶,这样就能在O(1)时间得到最小元素了。但这种思路不能保证最后压入的元素能够最先出栈,因此这个数据结构已经不是栈了。 我们接着想到在...原创 2018-05-07 22:21:32 · 457 阅读 · 1 评论 -
算法题:两个大数相加(java)
题目: 大数相加不能直接使用基本的int类型,因为int可以表示的整数有限,不能满足大数的要求。输入的两个大数可能正可能负分析: 首先需要判断两个大数的正负号,使用字符串来模拟小学数学中的两个数的加减法。代码:/** * 两个大数相加,输入的两个大数的正负号不确定 */public class Solution { public static void main...原创 2018-04-29 18:11:55 · 3452 阅读 · 0 评论 -
剑指offer第二版面试题13:机器人的运动范围(java)
题目描述: 地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左,向右,向上,向下移动一格,但不能进入行坐标和列坐标的位数之和大于k的格子。例如:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18;但它不能进入方格(35,38),因为3 + 5+3+8 = 19.请问该机器人最多能到达多少个格子?分析: 和面试题13类似,这个方格也可...原创 2018-04-28 23:49:53 · 645 阅读 · 0 评论 -
剑指offer第二版面试题12:矩阵中的路径(java)
问题描述: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串”bcced”的路径,但是矩阵中不包含”abcb”路径,因为字符串的第一个字符b...原创 2018-04-28 21:51:27 · 680 阅读 · 3 评论 -
剑指offer第二版面试题37:序列化二叉树(java)
题目描述: 请实现两个函数,分别用来序列化和反序列化二叉树。分析: 如图: 题目实际上就是用序列来表示一棵二叉树,然后还可以根据这个序列重建二叉树。对于上图中的树,以前序遍历为例,先访问到1,然后2,然后4,4的左右子结点都为空,可以用一个特殊字符$替代,所以上图中的二叉树前序遍历表示就是“1,2,4,$,$,$,3,5,$,$,6,$,$”。 重建的时候,访问的第一个结点...原创 2018-06-04 12:02:57 · 1556 阅读 · 4 评论 -
剑指offer第二版面试题44:数字序列中某一位的数字(java)
题目描述: 数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。分析思路: 寻找数学规律 跳过不同位数的数字,在相应位数中寻找 •以序列中第1001位为例: •序列前10位为0-9,跳过,再从后面找991位; •后面180位为10-9...原创 2018-07-09 08:35:46 · 756 阅读 · 0 评论 -
剑指offer第二版面试题45:把数组排成最小的数(java)
题目描述: 输入一个正整数数组,把数组里面所有的数字拼接排成一个数,打印能拼接出的所有数字中的一个。例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323。分析实例: 这个题目最直接的做法应该是先求出这个数组中的所有数字的全排列,然后把每个排列拼接起来,最后求出排列起来的数字的最小值。求数组的排列和面试题28非常相似。根据排列组合的只是,n个数字总共有n!排列,我...原创 2018-07-09 09:04:50 · 460 阅读 · 2 评论 -
常用的排序算法(Java实现)
如图所示,先给出排序算法的分类以及性能的比较: 1、冒泡排序 基本思想: 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。冒泡排序的示例: 算法实现:public void sort(int[] arr){ ...原创 2018-07-31 15:44:16 · 351 阅读 · 0 评论 -
剑指offer第二版面试题43:1~n整数中1出现的次数(java)
题目描述: 输入一个整数n,求从1到n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,和12。一共出现了5次。分析思路1:不考虑时间效率的解法,靠它想拿offer有点难 如果在面试的时候碰到这个问题,应聘者大多能想到最直观的方法,也就是累加1到n中每个整数1出现的次数。我们可疑每次通过对10求余数判断整数的个位数字是不是1。如果这个数字大于...原创 2018-07-07 12:17:53 · 790 阅读 · 1 评论 -
剑指offer第二版面试题42:连续子数组的最大和(java)
题目描述: 输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和18。分析思路: Step1.从头到尾逐个累加数组中的每个数字,初始化和为0;(nCurrSum=0,nGre...原创 2018-07-06 09:41:22 · 1231 阅读 · 0 评论 -
剑指offer第二版面试题41:数据流中的中位数(java)
题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。分析思路: 用两个堆保存数据,保证两个堆的数据保持平衡(元素个数相差不超过1)大顶堆存放的数据要比小顶堆的数据小当两个堆中元素为偶数个,将新加入元素加入到大顶堆,如果要加入的数据,比小顶堆的最小...原创 2018-07-05 09:48:05 · 1555 阅读 · 3 评论 -
剑指offer第二版面试题40:最小的k个数(java)
题目描述: 输入n个整数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。这道题最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这种思路的时间复杂度是O(nlogn),面试官会提示我们还有更快的算法。分析1:O(n)的算法,只有当我们可以修改输入的数组时可用 我们可以基于Partition函数...原创 2018-07-05 09:12:18 · 1045 阅读 · 0 评论 -
剑指offer第二版面试题48:最长不含重复字符的子字符串(java)
题目描述: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含从’a’到’z’的字符。例如,在字符串中”arabcacfr”,最长非重复子字符串为”acfr”,长度为4。分析思路: 使用动态规划,记录当前字符之前的最长非重复子字符串长度f(i-1),其中i为当前字符的位置。每次遍历当前字符时,分两种情况:1)若当前字符第一次出现,则最长非重...原创 2018-07-10 09:40:12 · 940 阅读 · 6 评论 -
剑指offer第二版面试题39:数组中出现次数超过一半的数字(java)
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例子说明:如输入一个长度为9的数组{ 1, 2, 3, 2, 2, 2, 5, 4, 2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 。分析1:基于Partition 函数的O(n)算法 数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序,那么排序之后位于数组中间的数字一定就是...原创 2018-07-03 10:07:04 · 1952 阅读 · 1 评论 -
剑指offer第二版面试题38:字符串的排列(java)
题目描述: 输入一个字符串,打印出该字符串中字符的所有排列。 例如输入字符串abc,则打印由字符a,b,c所能排列出来的所有字符串:abc,abc,bac,bca,cab,cba分析: 我们求整个字符串的排列,可以看成两步:首先求出所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。第二步固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面...原创 2018-07-03 08:42:38 · 1004 阅读 · 0 评论 -
剑指offer第二版面试题47:礼物的最大价值(java)
题目描述: 在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?分析思路: 利用循环的动态规划实现,使用辅助二维数组 •定义f(i,j)表示到达坐标为(i,j)的格子时能拿到的礼物总和的最大值; •有两种路...原创 2018-07-09 09:59:08 · 1565 阅读 · 0 评论 -
剑指offer第二版面试题46:把数字翻译成字符串(java)
题目描述: 给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。分析思路: 用递归自顶向下分析,用动态规划自低向上求解 •定义问题:当最开始的一个或者两个数字被翻译成一个字符后,我们接着翻译...原创 2018-07-09 09:22:22 · 1029 阅读 · 5 评论 -
剑指offer第二版面试题11:旋转数组的最小数字(java)
题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。解题思路: 1、暴力解法,从头到尾遍历一次,我们就能找出最小的元素,复杂度为O(n),但是没有利用输入的旋转数组的特性,肯定达不到面试官的要求。 2、二分查找,这里的数...原创 2018-04-28 21:02:08 · 630 阅读 · 0 评论 -
剑指offer第二版面试题29:顺时针打印矩阵(java)
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: 1, 2, 3, 4 5, 6, 7, 8 9, 10,11,12 13,14,15,16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.分析: 当遇到一个复杂的问题的时候,我们可以用图形来帮助我们来思考。由于是...原创 2018-05-05 17:07:56 · 3553 阅读 · 0 评论 -
剑指offer第二版面试题16:数值的整数次方(java)
题目描述: 实现函数double Power(double base,int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。自以为很简单的解法: 由于不需要考虑大数问题,这道题看起来很简单,可能不少应聘者在看到题目30秒后就能写出如下的代码:public static double power(double base, int exp...原创 2018-04-30 16:12:29 · 520 阅读 · 0 评论 -
剑指offer第二版面试题15:二进制中1的个数(java)
题目描述: 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2。可能引起死循环的解法: 这是一道很基本的考察二进制和位运算的面试题。题目不是很难,面试官提出问题之后,我们很快就可以形成一个基本的思路:先判断整数二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时原来处于(从右边数起)第二位被移到最后...原创 2018-04-30 12:02:22 · 570 阅读 · 0 评论 -
剑指offer第二版面试题14:剪绳子(java)
题目描述: 给定一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]* k[1] * … *k[m]可能的最大乘积是多少? 例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。分析: 1、求一个问题的最优解; 2、整体的问题的最优解是依赖各个子问题的...原创 2018-04-30 10:22:33 · 1239 阅读 · 0 评论 -
剑指offer第二版面试题9:用两个栈实现队列(java)
题目描述: 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能。分析: 我们通过一个具体的例子来分析该队列插入和删除元素的过程。首先插入一个元素a,不妨先把它插入到stack1,此时stack1 中的元素有{a},stack2为空。再压入两个元素b和c,还是插入到stack1中,此时st...原创 2018-04-17 22:20:37 · 702 阅读 · 0 评论 -
剑指offer第二版面试题8:二叉树的下一个节点(java)
题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。分析: 根据中序遍历的特点,要找到一个节点的下一个节点无非就是三种情况: 1、有右子树,这时只需要把其右孩子作为下一个遍历的(并不是要找的)节点,然后沿着该节点的左子树(如果有的话)出发,直到遇到叶子节点,那么该叶子节点就是其下一个要找的节点;...原创 2018-04-17 21:50:52 · 810 阅读 · 0 评论 -
剑指offer第二版面试题7:重建二叉树(java)
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树。假设输入的前序遍历和中序遍历的结果中不包含重复的数字。例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7,2,1,5,3,6,8},则重建出二叉树并输出它的头结点。在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但在中序遍历中,根节点的值在序列的中间,左子树的结点的值位于根节点的值的...原创 2018-04-17 21:28:18 · 2848 阅读 · 2 评论 -
剑指offer第二版面试题6:从尾到头打印链表(java)
题目描述: 输入一个链表,从尾到头打印链表每个节点的值。返回新链表。分析: 可以借助栈也可以使用递归代码如下:/** * 从尾到头打印列表 */public class PrintListReverse { public static void main(String[] args) { ListNode node1 = new ListNode...原创 2018-04-17 20:43:11 · 807 阅读 · 0 评论 -
剑指offer第二版面试题5:替换空格(java)
题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy”,则输出”We%20are%20happy”.原因:在网络编程中,如果URL参数中含有特殊字符,如:空格、“#”等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器识别的字符。转换规则是在“%”后面跟上ASCII码的两位十六进制的表示。比如:空格的ASCII码是32,即十六...原创 2018-04-17 19:49:17 · 1081 阅读 · 1 评论 -
剑指offer第二版面试题4:二维数组中的查找(java)
问题描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 1 2 8 92 4 9 124 7 10 136 8 11 15分析: 首先我们选取数组右上角的数字9.由于9大于7,并且9还是第4列的第一个(也是最小的)数字,因此7...原创 2018-04-17 19:34:12 · 850 阅读 · 0 评论 -
剑指offer第二版面试题3:数组中重复的数字(java)
题目一: 在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复的次数。请找出数组中任意一个重复的数字。例如如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。 分析: 解决这个问题的一个简单的方法是先把输入的数组排序。从排序的数组中找出重复的数字是件容易的事情,只需要从头到尾扫描排...原创 2018-04-17 17:35:47 · 2861 阅读 · 0 评论 -
剑指offer第二版面试题17:打印1到最大的n位数(java)
题目描述: 输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的3位数即999跳进面试官的陷阱: 这个题目看起来很简单。我们看到这个问题后,最容易想到的办法是求出最大的n位数,然后用一个循环从1开始逐个打印。于是我们很容易写出下面的代码。public static void print1ToMaxOfNDigits(int n) { ...原创 2018-04-30 17:17:28 · 811 阅读 · 0 评论 -
剑指offer第二版面试题18:删除链表中的节点(java)
题目一描述: 给定单链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。分析: 在单链表中删除一个节点,最常规的方法无疑是从链表的头结点开始,顺序遍历查找要删除的节点,并在链表中删除该节点。 比如图a所表示的链表中,我们要删除节点i,可以从链表的头节点a开始顺序遍历,发现节点h的m_PNext指向要删除的节点i,于是我们可疑把节点h的m_PNext指向i的下一个节点即为j。...原创 2018-05-02 10:22:09 · 827 阅读 · 0 评论 -
剑指offer第二版面试题19:正则表达式匹配(java)
题目描述: 请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配分析: 这道题的核心其实在于分析’‘,对于’.’来说,它和任意字符都匹配,可把其当做普通...原创 2018-05-02 11:02:46 · 560 阅读 · 2 评论 -
剑指offer第二版面试题28:对称的二叉树(java)
题目描述: 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树和它的镜像是一样的,那么它是对称的。分析: 对于一棵二叉树,从根结点开始遍历, 如果左右子结点有一个为NULL,那么肯定不是对称二叉树; 如果左右子结点均不为空,但不相等,那么肯定不是对称二叉树; 如果左右子结点均不为空且相等,那么 遍历左子树,遍历顺序为:当前结点,左子树,右子树; 遍历右子树,遍历...原创 2018-05-05 12:25:12 · 912 阅读 · 0 评论