面试-剑指offer刷题小结
临近毕业找工作,算法一直是大多数人的痛点,或者是准就业者的痛点,有错误欢迎指出,有不同思路,欢迎在评论贴出你的代码
不贰过先生
这个作者很懒,什么都没留下…
展开
-
字符串转换成整数(Java)
题目:字符串转换为整数。注意事项(思考点):(1)字符串中包含有非数字字符;(2)字符串中包含正负符号;(3)考虑最大的正整数;(4)考虑最小的负整数;(4)溢出。开始时我的想法只考虑了第一,第二种情况:/** * 将字符串转换为整数 1:非数字字符 2:正负号 * @author Peter */public class Main { public static void main(...原创 2018-05-27 09:24:26 · 13512 阅读 · 0 评论 -
求链表中倒数第K个结点(Java)
题目:求链表中倒数第K个结点思路:用两个指针,第一个指针先走k-1步,然后两个指针一起走,当第一个指针走到尾节点的时候。第二个指针指向的就是倒数第k个节点。代码:...原创 2018-05-28 20:48:40 · 2144 阅读 · 0 评论 -
二维数组中的查找(Java)
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。第一思路:在二维数组中选取一个数字,分3种情况来查找的过程。(1)选取的数字和target相等,则查找过程结束;(2)选取的数字小于target,则要查找的数字在当前选取项的右方或者下方;(3)选取的数字大于target,则要查...原创 2018-05-30 17:35:12 · 2411 阅读 · 1 评论 -
替换空格(Java)
题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy.”,则输出“We%20are%20happy.”。第一思路:(1):是在原来的字符串上做替换(一定要保证内存够用)还是在新创建的字符串并在新的字符串上做替换。因为“ ”替换成“%20”字符串的长度会增加;(2):最直观的做法是O(n^2)的解法;从头到尾扫描字符串,每一次碰到空格的时候做替换。由于是把一...原创 2018-05-31 09:51:59 · 5646 阅读 · 0 评论 -
重建二叉树(Java)
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表的结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;}第一思路:我的第一思路是从头到尾输出类比数组那样,于是乎想把链表中的链表结点的指针反转过来,改变链表的方向,然后实现从头到尾输出(结果为从尾到头输出),可是发现修改链表的指针,反转链表的结构比较麻烦。于是乎放弃。最优...原创 2018-06-01 14:22:32 · 7621 阅读 · 4 评论 -
从尾到头打印链表(Java)
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表的结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;}第一思路:我的第一思路是从头到尾输出类比数组那样,于是乎想把链表中的链表结点的指针反转过来,改变链表的方向,然后实现从头到尾输出(结果为从尾到头输出),可是发现修改链表的指针,反转链表的结构比较麻烦。于是乎放弃。(改...原创 2018-05-31 10:51:41 · 3307 阅读 · 0 评论 -
用两个栈实现队列(Java)
题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和队列头部删除结点的功能。template<typename T> class CQueue{ public: CQueue(void); ~CQueue(void); void appendTail(Const T& nod...原创 2018-06-02 09:27:59 · 3609 阅读 · 2 评论 -
旋转数组的最小数字(Java)
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。...原创 2018-06-02 22:38:45 · 1316 阅读 · 2 评论 -
菲波那切数列(Java)
题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下:知识点:递归:是在一个函数的内部调用这个函数自身。循环:则是通过设置计算的初始值及终止条件,在一个范围内重复运算。通常基于递归实现的代码比基于循环实现的代码要简介很多,更加容易实现。如果面试官没有特殊要求,应优先采用递归的实现方法。递归虽然简介明了,但是缺点很明显:递归是函数自身调用自身,而函数调用是有...原创 2018-06-03 09:08:22 · 5164 阅读 · 1 评论 -
青蛙上台阶问题(Java)
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。思想:首先如果只有1个台阶,那青蛙只有一种跳法;如果有两个台阶,青蛙有两种跳法:一个台阶一个台阶跳;一次跳两个台阶;如果有n(n > 2)个台阶,假设用函数f(n)表示总共跳的方法数,这时青蛙在第一次有两种选择:选择跳一个台阶,则剩下n-1个台阶故剩下的台阶有f(n-1)种跳法;选择跳两个台阶,则...原创 2018-06-03 10:05:36 · 3074 阅读 · 0 评论 -
铺地板问题(Java)
题目:我们可以利用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用8个2*1的小矩形无重叠地覆盖一个2*8的大矩形,总共有多少种方法。思路:原创 2018-06-03 10:32:20 · 1571 阅读 · 0 评论 -
二进制中1的个数(Java)
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。知识点:这道题是考查位运算。位运算一共有5种:与、或、异或、左移和右移。与运算特点:全真为真;或运算特点:全假为假;异或运算的特点:相同为假。左移:m<<n,表示把m左移n位。左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。右移:m&...原创 2018-06-03 11:19:45 · 4599 阅读 · 1 评论 -
数值的整数次方(Java)
题目:实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。第一思路:直接利用for循环,循环exponent次。代码:public double Power(double base, int exponent){ double result = 1.0; for (int i = 1;...原创 2018-06-04 10:05:52 · 2660 阅读 · 4 评论 -
打印1到最大的n位数(Java)
题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。第一思路:首先计算出n位数的最大十进制数,然后利用循环输出从1到最大的n位数。实现代码:public void printToMaxOfNDigits(int n){ long number = 1; int i = 0; while(i < n){ //利用while循环...原创 2018-06-04 15:00:13 · 8234 阅读 · 3 评论 -
两个整数相加(Java)
题目:定义一个函数,在该函数中可以实现任意两个整数的加法。思路:由于没有限定两个数的大小范围,我们也要把它当做大数问题来处理。上一篇博客实现了在字符串表示的数字上加1的功能,我们可以参考这个思路实现两个数字的相加功能。另外需要主要的一个问题是如果输入的数字中有负数,我们应该怎么处理?首先需要分情况,两个整数相加(整数包括正数、0、负数)。故(1):两个正数相加;(2)一个正数一个负数相加;(3)两...原创 2018-06-05 09:56:52 · 14301 阅读 · 1 评论 -
在O(1)时间删除链表结点(Java)
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:struct ListNode{ int m_nValue; ListNode* m_pNext;}void DeleteNode(ListNode ** pListHead, ListNode* pToBeDeleted);第一思路:时间复杂度为O(n)的方法从链表的头结点开始,顺序...原创 2018-06-05 11:58:17 · 1223 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数前面(Java)
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。第一思路时间复杂度O(n^2):看到这个题,我的脑海里就浮现了一个时间复杂度为O(n^2)的算法。即从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾就有一个空位,这时把该偶数放入这个空位,但是要在此位置(刚刚被移...原创 2018-06-05 15:55:34 · 1877 阅读 · 2 评论 -
反转链表(Java)
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。链表结点定义如下:struct ListNode{ int m_nKey, ListNode * m_pNext;}思路:为了正确地反转一个链表,需要调整链表中指针的方向。为了将复杂的过程说清楚,这里借助于下面的这张图片。上面的图中所示的链表中,h、i和j是3个相邻的结点。假设经过若干操作,我们已经把h结点之前的指...原创 2018-06-06 10:26:05 · 16735 阅读 · 1 评论 -
合并两个排序的链表(Java)
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如:输入下图中的链表1和链表2,则合并之后的升序链表如链表3所示。链表的结点定义如下:struct ListNode{ int m_nValue; ListNode* m_pNext;}思路:在合并两个链表的过程中。链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点。继续合并...原创 2018-06-06 11:15:33 · 668 阅读 · 0 评论 -
数的子树(Java)
题目:输入两颗二叉树A和B,判断B是不是A的子结构。二叉树结点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路:判断是不是子结构可以分为两步:(1)在树A中找到和B的根结点的值一样的结点R(实际上就是树的遍历,可以用递归方法去遍历,也可以用循环的方...原创 2018-06-06 12:18:50 · 526 阅读 · 0 评论 -
二叉树的镜像(Java)
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路:首先理解什么叫二叉树的镜像。我们都知道镜子具有左右相反的功能。故二叉树的镜像树是除根结点以外,其他结点都有顺序的左右交换了顺序。比如上面的图中所示:根结...原创 2018-06-06 14:38:32 · 1476 阅读 · 1 评论 -
顺时针打印矩阵(Java)
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵:1 2 3 45 6 7 89 10 11 1213 14 15 16则依次打印出数字1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10。思路:首先拿到这个题,读完题我们脑子里会呈现出这样的一个画面。从外圈到内圈顺序的依次打印,我们就可以把矩阵想象成若干个圈,如上图所示,我们...原创 2018-06-06 20:44:54 · 11471 阅读 · 0 评论 -
包含min函数的栈(Java)
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。思路:要使时间复杂度是O(1),需要每次压入一个新元素进栈时,将栈里的所有元素排序,让最小的元素位于栈顶。但是这种想法不能保证最后压入栈的元素能够最先出栈,因为这个数据结构已经不是栈了。于是借助于一个辅助的成员变量来存放最小的元素。每次压入一...原创 2018-06-07 09:13:13 · 2765 阅读 · 1 评论 -
栈的压入、弹出序列(Java)
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、 2、 3、 4、 5是某栈的压栈序列,序列4、 5、 3、 2 、1是该压栈序列对应的一个弹出序列,但4、 3 、5 、1 、2就不可能是该压栈序列的弹出序列。思路:首先借助一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从该栈中弹...原创 2018-06-07 09:51:28 · 3091 阅读 · 2 评论 -
从上往下打印二叉树(Java)
题目:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印。例如下图中的二叉树,则依次打印出8、 6、 10、 5、 7、 9、 11。二叉树结点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路:这道题实质是在考查树的遍历算法。只是这种...原创 2018-06-07 10:36:01 · 12613 阅读 · 4 评论 -
二叉搜索树的后序遍历序列(Java)
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true。否则返回false。假设输入的数组的任意两个数字都互不相同。思路:满二叉树:从高到低,除了叶结点外,所有结点的左右结点都存在。完全二叉树:比满二叉树少几个叶结点,从左向右放子结点。平衡二叉树:空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是平衡树。、二叉...原创 2018-06-07 15:10:07 · 6935 阅读 · 5 评论 -
二叉树中和为某一值的路径(Java)
题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。二叉树结点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路:...原创 2018-06-08 16:45:11 · 4595 阅读 · 2 评论 -
复杂链表的复制(Java)
题目:请实现函数ComplexListNode* Clone(ComplexListNode * pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。结点的C++定义如下:struct ComplexListNode{ int m_nValue; ComplexListNode* m_...原创 2018-06-09 10:46:04 · 5087 阅读 · 3 评论 -
二叉搜索树与双向链表(Java)
题目:输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向,比如输入下图中左边的二叉搜索树,则输出转换之后的排序双向链表。struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路1:在二叉树中,每个结点都有两...原创 2018-06-10 11:02:10 · 5312 阅读 · 4 评论 -
字符串的排列(Java)
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如:输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab、cba。思路:面对这样的题目,我们需要将复杂问题分解化,分解成一个一个小问题。将一个字符串分为两部分:第一部分为它的第一个字符,第二部分为后面所有的字符,如下图所示:求整个字符串的全排列,可以看成两步:第一步首先求所有可能出现在第一个...原创 2018-06-11 11:10:41 · 5238 阅读 · 0 评论 -
排列组合相关问题(Java)
题目:输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放到正方体的8个顶点上(如下图所示),使得正方体上三组相对的面上的4个顶点的和都相等。思路:相当于先得到a1、a2、a3、a4、a5、a6、a7和a8这8个数字的所有排列,然后判断有没有某一个的排列复合题目所给定的条件,即a1 + a2 + a3 + a4 == a5 + a6 + a7 + a8,a1 + a3 + a5 + a7 ...原创 2018-06-11 15:27:47 · 831 阅读 · 0 评论 -
数组中出现次数超过一半的数字(Java)
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。第一思路:...原创 2018-06-12 15:04:04 · 1277 阅读 · 0 评论 -
最小的k个数(Java)
题目:输入n个整数,找出其中最小的k个数。例如输入4、 5、 1、 6、 2、 7、 3、 8这8个数字,则最小的4个数字是1、 2、 3、 4。思路:O(n)的算法,只有当我们可以修改输入的数组是可用经典常用的算法,快速排序的精髓利用快速排序划分的思想,每一次划分就会有一个数字位于以数组从小到达排列的的最终位置index;位于index左边的数字都小于index对应的值,右边都大于index指向...原创 2018-06-14 19:30:27 · 4138 阅读 · 1 评论 -
连续子数组的最大和(Java)
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如:输入的数组为{1,-2, 3, 10, -4, 7, 2, -5},和最大的子数组为{3, 10, -4, 7, 2},因此输出为该子数组的和18。最直观的思路:一个长度为n的数组,总共有n(n + 1) / 2 个子数组;计算出所有子数...原创 2018-06-14 22:33:44 · 1267 阅读 · 1 评论 -
从1到n整数中1出现的次数(Java)
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1, 10, 11和12;1一共出现了5次。第一思路:利用for循环累加从1到n中每个整数出现1的次数。判断每个整数是否出现1,利用对整数每次对10求余,判断整数的个位数字是不是1。如果这个数字大于10,除以10之后再判断个位数字是不是1。代码实现:/** ...原创 2018-08-05 16:14:10 · 9224 阅读 · 1 评论 -
把数组排成最小的数(Java)
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如,输入数组{3, 32,321},则打印出这3个数字能排成的最小数字321323。第一思路:利用全排列,然后比较全排列中的数字,得出最小数字。代码实现:public class Main { public static void permutation(String[] ...原创 2018-08-05 18:46:18 · 3040 阅读 · 1 评论 -
丑数(Java)
题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。第一思路:逐个判断每个整数是不是丑数的解法,直观但不高效。注:所谓一个数m是另一个数n的因子,是指n能被m整除,也就是n%m == 0。根据丑数的定义,丑数只能被2、3和5整除。即一个数能被2整...原创 2018-08-07 08:44:22 · 1911 阅读 · 1 评论 -
第一个只出现一次的字符(Java)
题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出'b'。第一思路:借助于数组来做。开辟一个长度为26的数组,用来存放字符串中每个字符出现的次数。这样第一次扫描去统计这个字符串中字符出现的次数,第二次去统计第一个出现结果为1的次数,并输出对应的字符。public class Main { //输出0代表没有满足条件的 public stat...原创 2018-08-07 09:44:44 · 5721 阅读 · 2 评论 -
数组中的逆序对(Java)
题目:在数组中的两个数字如果前面的数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7, 5, 6, 4}中,一共存在5个逆序对,分别是(7,6)、(7,5)、(7,4)、(6、4)和(5,4)。思路:利用归并排序的思想实现数组中的逆序对的统计。第一步将7, 5, 6, 4;分为7和5;6和4,统计得出有两个逆序对。对7和5...原创 2018-08-24 15:42:52 · 1552 阅读 · 0 评论 -
两个链表的第一个公共结点(Java)
题目:输入两个链表,找出它们的第一个公共结点。链表结点的定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;}思路:第一种解法:蛮力(暴力)法。第二种解法:借助于栈的先进后出,由于找到两个链表的第一个公共结点,故这个链表在公共结点以后是一个Y字型,故我们将两个链表放入栈中,来找到栈中最后一个相同的结点,即为...原创 2018-08-24 16:20:58 · 1094 阅读 · 1 评论