剑指Offer Java实现
剑指Offer Java实现
带翅膀的猫
天天写BUG的软件开发工程师~
展开
-
剑指Offer:构建乘积数组
给定一个数组 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[i],每一次计算都要将A中除第 i 个元素外的所有元素相乘,则总的时间复杂度为O(n^2),这种解法不是最好的。构建矩阵解法我们将B[i]=A[0] x A[1]...原创 2018-04-01 22:08:14 · 3860 阅读 · 0 评论 -
剑指Offer:数组中重复的数字
      在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如:如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。  &原创 2018-03-23 15:12:48 · 3803 阅读 · 0 评论 -
剑指Offer:不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不能使用四则运算符号。 首先我们分析十进制的加法是如何运算的,譬如5+17=22。我们分三步计算:①各位相加但不进位,计算结果为12;②做进位操作,5+7中有进位,进位为10;③将前两步结果相加,12+10=22。 &nb...原创 2018-03-20 13:43:26 · 3765 阅读 · 0 评论 -
剑指Offer:求1+2+...+n
求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch…case等关键字及条件判断语句(A?B:C)对于剑指Offer书上介绍的四种方法都是C++的解法,不适用于JAVA。使用短路原则实现的递归解法实现代码:private static int Solution(int n){ int result=n; boolean value ...原创 2018-03-19 11:01:03 · 3870 阅读 · 0 评论 -
剑指Offer:圆圈中最后剩下的数字
0,1,……,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈最后剩下的那个数字。 这是著名的约瑟夫环问题,下面提供两种解法。经典解法:使用环形链表 自己创建一个环形链表比较麻烦,这里我使用LinkedList来模拟环形链表。但是LinkedList不是环形的,所有每当迭代器(it...原创 2018-03-18 13:10:25 · 3927 阅读 · 0 评论 -
剑指Offer:扑克的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看出任意数字。      大、小王是特殊的数字,我们不妨把它 们都定义为 0,这样就能和其他扑克牌区分开来了。   &原创 2018-03-01 15:33:29 · 3760 阅读 · 0 评论 -
剑指Offer:n个骰子的点数
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。      每个骰子的点数为1~6,n个骰子的点数和最小值为n,最大值为6n,所以n个骰子的点数和s有6n-n+1种情况(例如2个骰子的点数和有:2、3、4、5、6、7、8、9、10、11、12。共6*2-2+1=11种)。另外根据排列组合n...原创 2018-02-28 22:58:40 · 4057 阅读 · 0 评论 -
剑指Offer:翻转单词顺序 vs 左旋转字符串
题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内部的顺序不变。为简单起见 ,标点符号和普通字母一样处理。例如输入字符串”I am a student. ”,则输出”student. a am I”。 这是一道经典的算法题,使用两次翻转即可实现。我们能很顺畅的给面试官解释:第一次对整个字符串进行翻转,得到:“.stne...原创 2018-02-27 17:23:57 · 3769 阅读 · 0 评论 -
剑指Offer:和为s的两个数字VS和为s的连续正数序列
题目一:输入一个递增排序的数组和一个数字 s,在数组中查找两个数,得它们的和正好是 s。如果有多对数字的和等于 s,输出任意一对即可。      例如输入数组 {1,2,4,7,11,15} 和数字 15。由于 4+11=15,因此输出4和11 。   &原创 2018-02-27 14:56:08 · 3842 阅读 · 0 评论 -
剑指Offer:数组中只出现一次的数字
一个整型数组中除了两个数字之外,其他数字都是出现两次。请写程序这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。       例如数组{2,4,3,6,3,2,5,5},因为只有数字4和6这两个数字只出现了一次,其他数字都出现了两次,所以输出4和6。数组中只有一个数字是单独的,怎么解决?&nbsp原创 2018-02-26 23:20:23 · 3762 阅读 · 0 评论 -
剑指Offer:指定数字在排序数组中出现的次数
统计指定数字再排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在数组中出现了4次,输出4。使用二分查找法      由于数组是排序的我们应该很容易想到使用二分法查找指定数字。第一次查找中间值为3,等于我们要查找的数字,其他数字3可能在中间值的两侧,我们要查找到第一个3出现的位置和最后一个3出...原创 2018-02-25 16:26:15 · 3716 阅读 · 0 评论 -
剑指Offer:两个单链表的第一个公共结点
输入两个单链表,找出这两个链表的第一个公共结点。实验代码:https://pan.baidu.com/s/1jKemT6I解法一:暴力查找 遍历链表1,获得结点node1,再次遍历链表2,获得结点node2,比较node1和node2,如果相等说明找到结点,否则查找node2的下一个结点,继续比对,如果遍历完这个链表...原创 2018-02-24 21:44:38 · 3794 阅读 · 0 评论 -
剑指Offer:第一个只出现一次的字符
在字符串中找出第一个只出现一次的字符。如输入“abaccdeff”,则输出b。普通解法:遍历,时间复杂度为O(n2) 从头至尾遍历每个字符,比对每个字符后面有没有相同的字符,如果出现就遍历下一个字符,再次比对;否则找到我们需要的字符,返回结果。空间换时间解法:使用哈希表 &nbs...原创 2018-02-21 19:10:41 · 3993 阅读 · 0 评论 -
剑指Offer:丑数
我们把只包含因子 2、3 和 5 的数称作丑数 (Ugly Number)。求按从小 到大的顺序的第 1500 个丑数。例如 6、8都是丑数,但 14 不是,它包含因子 7。习惯上我们把 1当做第一个丑数。解法一:逐一判断是否是丑数,简单但是不够高效      数字n是数字m的因子说明m%n==0。丑数的因子只有2、3和5,说明一...原创 2018-02-19 22:07:21 · 3947 阅读 · 0 评论 -
剑指Offer:把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数, 打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321} ,则打印出这 3 个数字能排成的最小数字 321323.       最直接的方法就是求出这个数组的全排列,解法在剑指Offer:字符串的排列中详细介绍了,将全排列组成一个数字,再比较每个数字,得出最小值。n个...原创 2018-02-18 19:16:42 · 3928 阅读 · 0 评论 -
剑指Offer:从1到 n 整数中1出现的次数
输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次。解法一:暴力求解法      从1开始自增到指定的整数n,判断每一个数中的每一位是否为1,有1就进行统计。 实现代码很简单:private static int Numb...原创 2018-02-16 15:28:31 · 4964 阅读 · 2 评论 -
剑指Offer:连续子数组的最大和
输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值 。要求时间结复杂度为 O(n)。例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10 -4,7, 2} ,因此输出为该子数组的和18。解法一:举例分析数组的规律      我们试着从头到..原创 2018-02-14 21:06:51 · 3892 阅读 · 0 评论 -
剑指Offer:最小的K个数
输入n个整数(不重复),找出其中最小的k个数。例如输入4、5、1、6、2、7、3、8这8个数字,则输出最小的4个数为1、3、2、4。解法一:O(n)的解法,但是会修改原数组      从面试题数组中出现次数超过一半的数字中受到启发,在该题中我们在寻找下标为n/2的数字,那么我们可以转变思路,找下标为k-1的数字,找到后该数左边的就...原创 2018-02-13 18:00:14 · 3890 阅读 · 0 评论 -
剑指Offer:数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。基于快排划分思想的时间复杂度为O(n)的解法      如果一个数字出现的次数超过一半,那么如果我们将数组排序后位于中间的就是那个出现次数超过...原创 2018-02-13 00:07:32 · 3843 阅读 · 0 评论 -
剑指Offer:字符串的排列
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串“abc”,则打印出由a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。我们解这题时可以将字符串划分为两部分:首字符和后面的所有字符。首先求所有可能出现在第一个位置的字符,即把首字符和后面的字符交换。 下图是字符串abc所有字符出现在第一个位置的情形: 然后对后面部分的字符串进行第一步操作...原创 2018-02-11 21:22:47 · 5055 阅读 · 2 评论 -
剑指Offer:复杂链表的复制
请实现函数复制一个复杂链表。在复杂链表中,每个结点除了有一个next引用“指向”下一个结点外,还有一个sibling引用“指向”链表中的任意结点或者null。 复杂链表的图示: O(n^2)的解法,无法拿下offer第一反应的解决思路是两步走战略:第一步:先不管sibling引用的问题,先把整个链表中的每一个结点都复制并用next连接起来,这一步还是比较简单的;第二步:每个结点...原创 2018-02-10 15:01:40 · 3980 阅读 · 2 评论 -
剑指Offer:栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压站序列,序列4、5、6、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。 解决这一问题的直观解法就是使用一个辅助栈,把...原创 2018-02-08 15:37:22 · 3766 阅读 · 0 评论 -
剑指Offer:包含min函数的栈
定义栈的数据结构。请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。看到这个问题我们的第一反应是每压入一个元素就对栈中的元素进行排序,让最小的元素位于栈顶,这样就能在O(1)时间得到最小元素了。但是,这种方法可能会违背了栈先进后出的原则,那么这种类型就不是栈结构了。舍去这种方法。那我们在栈结构中声明一个变量,每次压入新的元原创 2018-02-04 18:48:24 · 3750 阅读 · 0 评论 -
剑指Offer:顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入以下矩阵: 则输出顺序为:1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。从外至里,每一圈都顺时针打印,所以每一圈的打印思路是差不多的,我们先试着打印最外面的一圈试试: 实现代码://打印一圈,start为起始点的坐标之一(起始点横纵坐标相等)private static原创 2018-02-03 16:57:41 · 3734 阅读 · 0 评论 -
剑指Offer:合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入下图中的链表1和链表2,则合并之后的升序链表如链表3所示: 链表的合并同链表的反转一样是经典的链表操作问题。 这这个问题中我们注意的点有:有一个链表是空的,则合并后的链表就是另外一个链表;两个链表都是空的,程序停止运行,报错;每次选择在两个数中选择更小的数进行插入新链表中是一个归并操作,使用递归原创 2018-02-03 19:12:54 · 3772 阅读 · 0 评论 -
剑指Offer:反转链表
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。反转链表是单链表学习过程中比较重要的一个知识点,为了防止断链的出现一般使用三个指针进行操作。操作流程: 实现代码: 单链表的创建参见[链表]private static LinkNode ReverseList(LinkNode head){ if(head==null){ th原创 2018-02-02 16:53:12 · 3786 阅读 · 0 评论 -
剑指Offer:链表中倒数第k个结点
输入一个单链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本提从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。如果这是个双向链表我们可以先找到尾结点再回溯到倒数第k个结点。可是这是单链表这种方法就不行了。 还有一种方法,首先遍历一遍链表,获取链表的长度n,那么得到倒数第k原创 2018-02-01 16:37:57 · 3825 阅读 · 0 评论 -
剑指Offer:调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整数组顺序使奇数位于数组前半部分,偶数位于数组后半部分。初步解法 从数组头部开始遍历,遇到偶数就将其后面的所有数字向前挪动一位,然后将该偶数插入到数组末尾,然后继续遍历,同理。当遍历完毕后所有的偶数就在后半部分,奇数就在前半部分了。这种解法的时间复杂度为O(n^2),可行但是太慢了,面试官没兴趣。只完成基本功能的解法,适用于初级程序员我们原创 2018-01-31 20:17:07 · 6015 阅读 · 9 评论 -
剑指Offer:在O(1)时间内删除链表结点
题目:给定单向链表和一个指定的结点,定义一个函数在O(1)时间删除该结点。 在以往的删除结点中我们所用的方法是从头结点开始一个个的遍历到指点结点的前一个结点再进行删除,因为我们无法通过当前结点找到前一个结点,这种方法的时间复杂度为O(n)。 现在摆在我们面前的一个问题就是我们是不是一定要得到删除结点的前一个结点呢?答案是否定的。我们应该换一种思路进行删除:将要删除结点的原创 2018-01-30 20:00:49 · 3966 阅读 · 0 评论 -
剑指Offer:打印1到最大的n位数
输入数字n,按顺序打印从1最大的n位十进制数。比如输入3,则打印出1,2,3一直到最大的3位数即999。进坑的解法public static void Print1ToMaxOfNDigits(int n){ int num=1; int i=0; while(i<n){ num *= 10; i++; } for原创 2018-01-30 16:00:07 · 3772 阅读 · 0 评论 -
剑指Offer:数值的整数次方
实现函数double Power(double base,int exponent),求base的exponent次方。不得使用库函数,同事不考虑大数问题。不加思索的最low版本public static double Power(double base,int exponent){ double result=1.0; for(int i=0;i<exponent;i原创 2018-01-29 18:55:51 · 3694 阅读 · 0 评论 -
剑指Offer:二进制中1的个数
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2个1.因此如果输入9,该函数输出2。初级解法:转成二进制统计1的个数二进制转换规则:模二取余 将一个正数转成二进制很简单,注意遇到输入负数的情况。public static int NumberOf1(int num){ int[] binary = new int[32];原创 2018-01-26 22:42:32 · 3732 阅读 · 0 评论 -
剑指Offer:斐波那契数列
写一个函数,输入n,求斐波那契数列的第n项。斐波那契数列的定义如下: 说起斐波那契数列对于广大程序员是无人不知呀!对于此问题的解法—–递归。更是深入人心。public static long Fibonacci(int n){ if(n0){ return 0; } if(n==1){ return 1; } r原创 2018-01-25 16:38:31 · 3793 阅读 · 0 评论 -
剑指Offer:旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个已排序(由小到大)数组的一个旋转数组,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转数组,该数组的最小值为1。对于在数组中找最小数字的问题最容易想到也是最容易实现的就是遍历一遍,时间复杂度为O(n),但是这并没有利用旋转数组的特点(两部分增序排列),无法让面试官满意。拿题目中原创 2018-01-24 16:13:15 · 3787 阅读 · 0 评论 -
剑指Offer:两个栈实现队列
用两个栈实现一个队列。要求实现两个方法:appendTail()和deleteHead(),分别完成在队列尾部添加元素和头部删除元素的功能。我们必须了解栈和队列的特点才能完成这一问题,栈:先进后出,队列:先进先出。 设计思路: 我们将a,b,c压入stack1中,此时c在栈顶,删除数据不能在stack1中进行,我们可以将stack1中的数据全部弹出并且压入stack2中,然后对stack2原创 2018-01-23 19:42:55 · 3739 阅读 · 0 评论 -
剑指Offer:从尾到头打印单链表
输入一个链表的头结点,从尾到头反过来打印出每一个结点的值。 一想到打印单链表我们第一反应是从头到尾输出会特别简单,如果要从尾到头打印我们会想把整个链表中的next域反过来,但是这是改变聊表结构的一种方法可不可以使用看面试官,如果不能使用该怎么办呢? 原本是从头到尾的输出现在需要从尾到头的输出,先进的后出来(FILO),不难想到使用栈来实现,而递归的本质就是栈,所以我原创 2018-01-22 15:55:58 · 3746 阅读 · 0 评论 -
剑指Offer:替换空格
请实现一个函数,把字符数组中的每个空格替换为”%20”。例如输入”we are happy.”则输出”we%20are%20happy.” 原来的一个空格被替换为‘%’‘2’‘0’我们不能想当然的直接赋值字符,而必须将空格后面的所有字符都后移两个位置否则会覆盖原来的字符。时间复杂度为O(n^2)的解法,不足以拿到Offer在我们平常看到数组这玩意儿时我们总是从前往后遍历,同样在解答这题时原创 2018-01-20 18:15:06 · 3814 阅读 · 0 评论 -
剑指Offer:二维数组查找
存在这样的一个二维数组,它的每一行都按照从左至右的递增顺序排序,每一列都按照从上至下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 示例: 在此二维数组中查找数字7,查找成功返回true;在此数组中查找数字5,查找失败返回false。如果你说遍历数组那就没意思了,这也谈不上什么好方法。必挂你!!算法思路原创 2018-01-19 11:25:31 · 3829 阅读 · 0 评论 -
剑指Offer:实现单例模式
在所有的设计模式中面试最容易提及的就是单例模式了,对于单例模式我们一定不陌生,单例模式具有以下特点:单例类只能有一个实例。单例类必须自己创建自己的唯一实例。单例类必须给所有其他对象提供这一实例。版本一:最简单的写法,只能适用于单线程public class Singleton { private static Singleton instance = null;原创 2018-01-18 18:47:38 · 4018 阅读 · 0 评论