
剑指offer
不贰过先生
这个作者很懒,什么都没留下…
展开
-
翻转单词顺序VS左旋转字符串(Java)
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串“I am a student.”,则输出"student. a am I"。思路:思路一:先将整个英语句子中每个单词翻转即将“I am a student.”翻转成“I ma a .tneduts ”。然后再将整个句子翻转就变成"student. a am I"...原创 2018-08-25 19:32:22 · 440 阅读 · 0 评论 -
丑数(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 · 1983 阅读 · 1 评论 -
把数组排成最小的数(Java)
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如,输入数组{3, 32,321},则打印出这3个数字能排成的最小数字321323。第一思路:利用全排列,然后比较全排列中的数字,得出最小数字。代码实现:public class Main { public static void permutation(String[] ...原创 2018-08-05 18:46:18 · 3138 阅读 · 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 · 9387 阅读 · 1 评论 -
二叉搜索树与双向链表(Java)
题目:输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向,比如输入下图中左边的二叉搜索树,则输出转换之后的排序双向链表。struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路1:在二叉树中,每个结点都有两...原创 2018-06-10 11:02:10 · 5367 阅读 · 4 评论 -
用两个栈实现队列(Java)
题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和队列头部删除结点的功能。template<typename T> class CQueue{ public: CQueue(void); ~CQueue(void); void appendTail(Const T& nod...原创 2018-06-02 09:27:59 · 3660 阅读 · 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 · 5136 阅读 · 3 评论 -
二叉树中和为某一值的路径(Java)
题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。二叉树结点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}思路:...原创 2018-06-08 16:45:11 · 4638 阅读 · 2 评论 -
重建二叉树(Java)
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表的结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;}第一思路:我的第一思路是从头到尾输出类比数组那样,于是乎想把链表中的链表结点的指针反转过来,改变链表的方向,然后实现从头到尾输出(结果为从尾到头输出),可是发现修改链表的指针,反转链表的结构比较麻烦。于是乎放弃。最优...原创 2018-06-01 14:22:32 · 7665 阅读 · 4 评论 -
连续子数组的最大和(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 · 1318 阅读 · 1 评论 -
二叉搜索树的后序遍历序列(Java)
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true。否则返回false。假设输入的数组的任意两个数字都互不相同。思路:满二叉树:从高到低,除了叶结点外,所有结点的左右结点都存在。完全二叉树:比满二叉树少几个叶结点,从左向右放子结点。平衡二叉树:空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是平衡树。、二叉...原创 2018-06-07 15:10:07 · 6998 阅读 · 5 评论 -
第一个只出现一次的字符(Java)
题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出'b'。第一思路:借助于数组来做。开辟一个长度为26的数组,用来存放字符串中每个字符出现的次数。这样第一次扫描去统计这个字符串中字符出现的次数,第二次去统计第一个出现结果为1的次数,并输出对应的字符。public class Main { //输出0代表没有满足条件的 public stat...原创 2018-08-07 09:44:44 · 5828 阅读 · 2 评论 -
圆圈中最后剩下的数字(Java)
题目:0, 1,....., n - 1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。代码实现:一:利用数组实现public static int getLastNum(int n, int m){ if(n < 1 || m < 1){ //表示输入的非法 return -1; } int num[...原创 2018-08-27 15:31:39 · 774 阅读 · 0 评论 -
求1+2+...+n(Java)
题目:求1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。代码实现:public static int sum(int n){ int result = 0; int a = 1; boolean value = ((n!=0) && a==(result = sum(n-1)...原创 2018-08-27 15:53:52 · 809 阅读 · 0 评论 -
和为s的两个数字VS和为s的连续正数序列(Java)
题目:输入一个递增排序的数组和一个数字s,在数组在查找两个数,使得它们的和正好是。如果有多对数字的和等于s,输出任意一对即可。例如:输入数组{1、2、4、7、11、15}和数字15。由于4 + 11 = 15,因此输出4 和 11。思路:直观的思路:遍历数组两遍,即每一个数字和后面的数字相加看是否等于15,是直接返回,否则继续遍历直到找到或者遍历结束为止。时间复杂度O(n^2)。...原创 2018-08-25 16:39:09 · 276 阅读 · 0 评论 -
数组中只出现一次的数字(Java)
题目:一个整型数组里面除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字,要求时间复杂度是O(n),空间复杂度是O(1)。思路:利用异或去重的思想代码实现:public class Main { public static void findNumsAppearOne(int nums[]){ int len = nums.length;...原创 2018-08-25 15:57:08 · 2403 阅读 · 1 评论 -
二叉树的深度(Java)
题目:输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。二叉树的结点定义:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;};树的结构体publi...原创 2018-08-25 15:19:39 · 535 阅读 · 0 评论 -
数组中重复的数字(Java)
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字2或者3。代码实现:public static boolean getRepeatNums(int numbers[...原创 2018-08-28 20:47:21 · 584 阅读 · 0 评论 -
数字在排序数组中出现的次数(Java)
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。思路:第一种解法:蛮力法,顺序遍历数组,统计出数字3出现的次数,不过这时就没有利用到题目中给的有序,故时间复杂度过大,不符合要求。第二种解法:利用二分查找的思想(时间复杂度log(n))来解决问题。首先先找到数组中3出现的第一...原创 2018-08-24 17:17:06 · 3574 阅读 · 0 评论 -
两个链表的第一个公共结点(Java)
题目:输入两个链表,找出它们的第一个公共结点。链表结点的定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;}思路:第一种解法:蛮力(暴力)法。第二种解法:借助于栈的先进后出,由于找到两个链表的第一个公共结点,故这个链表在公共结点以后是一个Y字型,故我们将两个链表放入栈中,来找到栈中最后一个相同的结点,即为...原创 2018-08-24 16:20:58 · 1155 阅读 · 1 评论 -
数组中的逆序对(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 · 1582 阅读 · 0 评论 -
树中两个结点的最低公共祖先(Java)
题目:树中两个结点的最低公共祖先。解决方法一:假设是二叉搜索树(二叉搜索树是一个排序的二叉树,左子树的结点小于根结点,右子树的结点大于根结点),故找到一个结点,使其大于左子结点小于右子结点即可。代码实现:public static TreeNode getLastCommonNode(TreeNode pRoot, TreeNode pLeft, TreeNode pRigh...原创 2018-08-28 15:48:21 · 3248 阅读 · 2 评论 -
把字符串转化成整数(Java)
题目:把字符串转化为整数代码实现:public static boolean g_status = true; //代表是否非法输入public static boolean g_overflow = false; //代表是否溢出public static int strToInt(String str) { if (str == "" || str.length() == ...原创 2018-08-27 16:33:32 · 1270 阅读 · 0 评论 -
不用加减乘除法做加法(Java)
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+,-,*,/;四则运算符号。代码实现:public int add(int num1, int num2) { while(num2 != 0){ int tmp = num1 ^ num2; //不算进位各位相加 num2 = (num1&num2)<<1; //得到进位数 num1 = t...原创 2018-08-27 16:07:39 · 491 阅读 · 0 评论 -
从上往下打印二叉树(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 · 12713 阅读 · 4 评论 -
栈的压入、弹出序列(Java)
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、 2、 3、 4、 5是某栈的压栈序列,序列4、 5、 3、 2 、1是该压栈序列对应的一个弹出序列,但4、 3 、5 、1 、2就不可能是该压栈序列的弹出序列。思路:首先借助一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从该栈中弹...原创 2018-06-07 09:51:28 · 3161 阅读 · 2 评论 -
从尾到头打印链表(Java)
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表的结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;}第一思路:我的第一思路是从头到尾输出类比数组那样,于是乎想把链表中的链表结点的指针反转过来,改变链表的方向,然后实现从头到尾输出(结果为从尾到头输出),可是发现修改链表的指针,反转链表的结构比较麻烦。于是乎放弃。(改...原创 2018-05-31 10:51:41 · 3368 阅读 · 0 评论 -
求链表中倒数第K个结点(Java)
题目:求链表中倒数第K个结点思路:用两个指针,第一个指针先走k-1步,然后两个指针一起走,当第一个指针走到尾节点的时候。第二个指针指向的就是倒数第k个节点。代码:...原创 2018-05-28 20:48:40 · 2188 阅读 · 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 · 880 阅读 · 0 评论 -
打印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 · 8325 阅读 · 3 评论 -
字符串的排列(Java)
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如:输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab、cba。思路:面对这样的题目,我们需要将复杂问题分解化,分解成一个一个小问题。将一个字符串分为两部分:第一部分为它的第一个字符,第二部分为后面所有的字符,如下图所示:求整个字符串的全排列,可以看成两步:第一步首先求所有可能出现在第一个...原创 2018-06-11 11:10:41 · 5385 阅读 · 0 评论 -
数值的整数次方(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 · 2712 阅读 · 4 评论 -
二进制中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 · 4695 阅读 · 1 评论 -
铺地板问题(Java)
题目:我们可以利用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用8个2*1的小矩形无重叠地覆盖一个2*8的大矩形,总共有多少种方法。思路:原创 2018-06-03 10:32:20 · 1614 阅读 · 0 评论 -
字符串转换成整数(Java)
题目:字符串转换为整数。注意事项(思考点):(1)字符串中包含有非数字字符;(2)字符串中包含正负符号;(3)考虑最大的正整数;(4)考虑最小的负整数;(4)溢出。开始时我的想法只考虑了第一,第二种情况:/** * 将字符串转换为整数 1:非数字字符 2:正负号 * @author Peter */public class Main { public static void main(...原创 2018-05-27 09:24:26 · 13587 阅读 · 0 评论 -
青蛙上台阶问题(Java)
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。思想:首先如果只有1个台阶,那青蛙只有一种跳法;如果有两个台阶,青蛙有两种跳法:一个台阶一个台阶跳;一次跳两个台阶;如果有n(n > 2)个台阶,假设用函数f(n)表示总共跳的方法数,这时青蛙在第一次有两种选择:选择跳一个台阶,则剩下n-1个台阶故剩下的台阶有f(n-1)种跳法;选择跳两个台阶,则...原创 2018-06-03 10:05:36 · 3110 阅读 · 0 评论 -
菲波那切数列(Java)
题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下:知识点:递归:是在一个函数的内部调用这个函数自身。循环:则是通过设置计算的初始值及终止条件,在一个范围内重复运算。通常基于递归实现的代码比基于循环实现的代码要简介很多,更加容易实现。如果面试官没有特殊要求,应优先采用递归的实现方法。递归虽然简介明了,但是缺点很明显:递归是函数自身调用自身,而函数调用是有...原创 2018-06-03 09:08:22 · 5255 阅读 · 1 评论 -
两个整数相加(Java)
题目:定义一个函数,在该函数中可以实现任意两个整数的加法。思路:由于没有限定两个数的大小范围,我们也要把它当做大数问题来处理。上一篇博客实现了在字符串表示的数字上加1的功能,我们可以参考这个思路实现两个数字的相加功能。另外需要主要的一个问题是如果输入的数字中有负数,我们应该怎么处理?首先需要分情况,两个整数相加(整数包括正数、0、负数)。故(1):两个正数相加;(2)一个正数一个负数相加;(3)两...原创 2018-06-05 09:56:52 · 14442 阅读 · 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 · 1272 阅读 · 0 评论 -
数组中出现次数超过一半的数字(Java)
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。第一思路:...原创 2018-06-12 15:04:04 · 1328 阅读 · 0 评论