剑指offer
剑指offe阅读笔记
baboon_chen
My piano is the keyboard
展开
-
面试过程
原创 2019-08-31 00:04:02 · 171 阅读 · 0 评论 -
从1到n整数中1出现的次数 ----《剑指offer》面试题32
题目输入一个整数N, 求从1到N这N个整数的十进制表示中,1出现的次数。例如:1-12中,1出现了: 1, 10 ,11,12 共5次思路一:暴力求解,从1遍历到n,求出每个数字1出现的次数二:递归求解,以数字21345为例 (1)将21345个数字分为两组。第一组为 1346~21345 共 20000个数字;第二组为 1 ~ 1345 共 1345个数字; (2)求第一组...原创 2019-08-16 21:29:04 · 187 阅读 · 0 评论 -
最小的k个数 ----《剑指offer》面试题30
题目输入n个整数,找出其中最小的K个数。思路一: 如果基于数组的第K个数字来调整,使得比第K个数字小的所有数字都位于数组的左边,比第K个数字大的所有数字都位于数组的右边。这样调整之后,位于数组中左边的K个数字就是最小的K个数字。#include <iostream>#include <random>using namespace std;/...原创 2019-08-13 09:19:03 · 153 阅读 · 0 评论 -
丑数 ----《剑指offer》面试题34
题目 我们把只包含因子2、3和5的数称作丑数(Ugly Number)。 求按从小到大的顺序的第1500个丑数。1是一个特殊的丑数。我们可以通过下面的函数来判断一个数是不是丑数: bool IsUgly(int number) { while(number % 2 == 0) number /= 2; while(number ...原创 2019-08-21 15:04:19 · 141 阅读 · 0 评论 -
数组中只出现1次的数字 ----《剑指offer》面试题40
题目一个整形数组里除了两个数字之外,其它的数字都出现了两次。找到这两个只出现一次的数字。思路异或运算的一个性质: 任何一个数字异或它自己都等于0。 也就是说,如果我们从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字,因为那些成对出现两次的数字全部在异或中抵消了。代码#include <iostream>using namespace...原创 2019-08-24 17:56:16 · 193 阅读 · 0 评论 -
连续子数组的最大和 ----《剑指offer》面试题31
题目输入一个整形数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。思路一:遍历从数组的第一个元素开始遍历。用nGreatestSum记录子数组的和的最大值。用nCurSum记录依次累加元素的和。如果nCurSum已经是负数,则可以将nCurSum重新赋值为当前元素的值;否则,继续累加。每遍历一个元素,将nGreat...原创 2019-08-14 21:56:07 · 168 阅读 · 0 评论 -
二叉树的深度 ----《剑指offer》面试题39
题目输入一棵二叉树的根结点,求该树的深度。思路如果一棵树只有一个结点,它的深度为1。如果根结点只有左子树,那么树的深度应该是该其左子树的深度加1;同样如果根结点只有右子树而没有左子树,那么树的深度是其右子树的深度加1。如果既有右子树又有左子树,那该树的深度就是其左、右子树的深度较大值再加1。题目输入一棵二叉树的根结点,判断该树是不是平衡二叉树。思路在遍历树的每个结点的时...原创 2019-08-23 16:17:29 · 160 阅读 · 0 评论 -
把数组排成最小的数 ----《剑指offer》面试题33
题目 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这3个数组能排成的最小数字321323。思路 (1) 将数组中的每个数字转换成字符串 (2) 定义A、B两个数字的排序规则,如果 AB < BA ,则 A < B (3) 利用qsort函数,将所有字符串进行排序 (4) 依次打...原创 2019-08-19 15:11:31 · 207 阅读 · 0 评论 -
数组中出现次数超过一半的数字 ----《剑指offer》面试题29
题目数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。思路一: 利用排序,将数组以从小到大的顺序排序,那这个超过一半的数字就是这个序列的中位数,位于数组中间位置。 找到的中位数就是我们想要的结果。但是排序如果直接用排序算法,则效率为O(nlgn)。可以借鉴快排的思想,取数组中一个数,将比这个数小的数放于它的左边, 比它大的数放于右边。 如果这个数位于数组中间位置,则...原创 2019-08-08 19:08:07 · 187 阅读 · 0 评论 -
正方体上三组对面上的4个顶点的和都相等----《剑指offer》
题目 输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放到正方体的8个顶点上,使得正方体三组相对的面上的4个顶点的和都相等。思路代码#include <iostream>using namespace std;// 判断条件// 下标0-7分别对应正方体编号1-8的顶点bool checking(int data[8]){ bool...原创 2019-07-23 10:23:21 · 481 阅读 · 0 评论 -
字符串的组合----《剑指offer》
题目 求字符串的所有组合,如字符串"ABC",它的组合有,A,B,C,AB,AC,BC,ABC。思路 分治思想解决组合问题。如果输入n个字符,则这n个字符能构成长度为1的组合、长度为2的组合、…、长度为n的组合。在求n个字符的长度为m(1<=m<=n)的组合的时候,我们把这n个字符分成两部分:第一个字符和其余的所有字符。如果组合里包含第一个字符,则下一步在剩余的字符里选...原创 2019-07-22 10:23:59 · 206 阅读 · 0 评论 -
第一个只出现一次的字符 ----《剑指offer》面试题35
题目在字符串中找出第一个只出现一次的字符。如输入“abaccdeff”,则输出’b’。思路利用hash map来统计每个字符出现的次数。hash数组的长度为256,代表256个字符。遍历字符串中的每个字符,对每个字符出现的次数进行统计。最终遍历hash数组,取出第一个只出现一次的字符。代码#include <iostream>#include <memory....原创 2019-08-22 11:44:48 · 150 阅读 · 0 评论 -
数组中的逆序对 ----《剑指offer》面试题36
题目在数组中两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。思路(1)先把数组分隔成两个子数组。用递归方法分别求每个子数组中的逆序对的数量。(2)子数组最终细化到只包含两个数字或者一个数字。(3)先统计出子数组内部的逆序对的数目。(4)然后再统计出两个相邻子数组之间的逆序对的数目。通过归并排序,如果子数组A中末尾的数...原创 2019-08-22 17:41:09 · 190 阅读 · 0 评论 -
树中两个结点的最低公共祖先 ----《剑指offer》面试题50
题目求树中两个结点的最低公共祖先,此树不是二叉树,并且没有指向父节点的指针。思路一: 如果是二叉搜索树 位于左子树的结点都比父结点小,而位于右子树的结点都比父结点大。那么在树中从上到下找到的第一个在两个输入结点的值之间的结点,就是最低的公共祖先。 二: 如果不是二叉搜索树,但是每个结点有指向父结点的指针 组织两条链表,每个链表是由叶结点指向根结点的路径。从而将问题转换成:求两个...原创 2019-08-30 23:34:44 · 502 阅读 · 0 评论 -
把字符串转换成整数 ----《剑指offer》面试题49
题目实现C语言的库函数atoi。思路实现简单,但是要考虑各种输入情况,以及返回的情况。(1) 输入的字符串是无效的字符串或者空串;(2) 输入的字符串带有正负符号;(3) 正负符号之后,没有紧接数字;(4) 输入的字符串中,有其它非数字字符;(5) 转换成int类型时,字符串的值会溢出(上溢与下溢);(6) 数字的结尾不是正常结尾;(7) 正确区分返回值为0 与 非正常返...原创 2019-08-30 15:13:18 · 163 阅读 · 0 评论 -
不用加减乘除做加法 ----《剑指offer》面试题47
题目写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/ 四则运算符号。思路利用位运算实现加法运算。假设这两个数是5(num1)和17(num2),5的二进制是101,17的二进制是10001。把计算分成三步:(1) 将两个数进行异或操作,得到的结果是两个数相加,但没有考虑进位的结果 --> sum。(2) 将两个数进行与操作,再将结果左移1位,得到的是5和17...原创 2019-08-30 11:18:27 · 199 阅读 · 0 评论 -
求1+2+...+n ----《剑指offer》面试题46
题目求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句(A?B:C)。思路除了用公式 sum = n(n+1)/2 之外,无外乎循环和递归两种思路。那只能找寻其它方法代替循环与递归。代码#include <iostream>using namespace std;// ---------...原创 2019-08-30 10:40:54 · 179 阅读 · 0 评论 -
圆圈中最后剩下的数字 ----《剑指offer》面试题45
题目从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字。思路一用模板库中的std::list来模拟一个环形链表。由于std::list本身不是一个环形结构,因此每当迭代器扫描到末尾的时候,我们要记得把迭代器移动到链表的头部,这样就相当于在一个圆圈里遍历了。时间复杂度:O(n * m)...原创 2019-08-29 18:18:05 · 211 阅读 · 0 评论 -
扑克牌的顺子 ----《剑指offer》面试题44
题目从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字。思路思路:把大小王看成0,把5张牌看成5个数字组成的数组。(1)把数组排序;(2)统计数组中0的个数。(3)统计排序之后的数组中相邻数字之间的空缺总数。(4)比较“空缺”的总数是否大于0的个数,如果大于,则返回false。...原创 2019-08-29 15:14:01 · 193 阅读 · 0 评论 -
n个骰子的点数 ----《剑指offer》面试题43
题目把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。思路一n个骰子的总点数,最小为n,最大为6n,根据排列组合的知识,那个骰子,所有点数的排列数为6^n。我们先统计每一个点数出现的次数,然后把每一个点数出现的次数除以6n,就能求出每个点数出现的概率。(1)先把骰子分成两堆,第一堆只有一个,第二堆有n-1个;(2)单独的那一个可能出现1...原创 2019-08-29 13:11:49 · 310 阅读 · 0 评论 -
翻转单词顺序VS左旋转字符串 ----《剑指offer》面试题42
题目一输入一个英文句子,翻转句子中的单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student. a am I"。思路(1)先将整个字符串翻转;(2)将每个单词翻转;朋友建议,以后做题最好自己求出算法复杂度,认真听取了。时间复杂度:O(n)空间复杂度:O(n)题目二字符串的左旋转...原创 2019-08-28 15:18:40 · 264 阅读 · 0 评论 -
和为s的两个数字VS和为s的连续正数序列 ----《剑指offer》面试题41
题目一输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。例如输入数组{1、2、4、7、11、15}和数字15。由于 4+11 = 15,因此输出4和11。思路(1)由于数组是一个递增序列,所以要查找的两个数中有一大一小,分别定义为small、big;(2)small指向数组的首元素,big指向数组的尾元素。通过...原创 2019-08-27 19:07:09 · 152 阅读 · 0 评论 -
两个链表的第一个公共结点 ----《剑指offer》面试题37
题目输入两个链表,找出它们的第一个公共结点。思路(1)将两个链表A、B分别压入两个不同的栈中。(2)两个栈同时弹出栈顶元素进行比较,直到找到最后一个相同的栈顶元素,就是A、B两个链表中的第一个公共结点。代码#include <iostream>#include <stack>using namespace std;struct ListNode...原创 2019-08-22 19:44:46 · 219 阅读 · 0 评论 -
8皇后问题用全排列方法解决----《剑指offer》
题目例如,其中一种解:1 0 0 0 0 0 0 00 0 0 0 1 0 0 00 0 0 0 0 0 0 10 0 0 0 0 1 0 00 0 1 0 0 0 0 00 0 0 0 0 0 1 00 0 0 1 0 0 0 0思路 我们可以将棋盘用一个二维数组表示,棋盘上用0代表不同的位置,1表示皇后所在的位置。由于每一行只能有一个皇后,并且皇后不能处于同一列...原创 2019-07-25 07:52:04 · 233 阅读 · 0 评论 -
字符串的全排列 ----《剑指offer》面试题28
题目 输入一个字符串,打印出该字符串中字符的所有排列。如:abc的所有排列有:abc、acb、bac、bca、cab、cba六种。思路 利用分治方法,把一个字符串看成由两部分组成:第一部分为它的第一个字符,第二部分是后面的所有字符。我们求整个字符串的排列,可以看成两步: 首先求所有可能出现在第一个位置的字符,即把第一个字符与后面所有的字符交换。 再求后面所有字符的排列。同样...原创 2019-07-19 10:55:50 · 161 阅读 · 0 评论 -
二叉搜索树的后序遍历序列 ----《剑指offer》面试题24
题目输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。假设输入的数组的任意两个数字都互不相同。思路二叉搜索树后序遍历时,最后一个数字是树的根结点。数组中前面的数字分为两部分:第一部分是左子树结点的值,它们都比根结点的值小;第二部分是右子树结点的值,它们都比根结点大。同理,左子树、右子树又可以看成一个小的二叉搜索树,用递归的方式可以判断,左子树结点的值是否小于根结点,右子...原创 2019-07-12 09:09:20 · 102 阅读 · 0 评论 -
打印1到最大的n位数
题目输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的最大的3位数即999。注意点当输入的n很大的时候,最大的n位数用int或者long long都会溢出。- 解法一:在字符串上模拟数字加法#include <iostream>#include <string.h>// 字符串自增1bool Increme...原创 2019-03-31 18:00:23 · 214 阅读 · 0 评论 -
数值的整数次方
题目实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。注意点当指数为负数时,先对指数求绝对值,然后算出次方的结果后再取倒数。如果底数(base)是0,且指数是负数时,提示出错。#include <iostream>// 设置全局变量,表示函数调用时,输入...原创 2019-03-27 00:19:01 · 123 阅读 · 0 评论 -
旋转数组的最小数字--二分查找
题目把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 {3, 4, 5, 1, 2} 为 {1, 2, 3, 4, 5} 的一个旋转,该数组的最小值为 1 。解题思路二分查找head,mid, tail,分别表示查找范围的头,中间,末尾的值。先求取mid的值,当mid>=head,则最小值必在m...原创 2019-03-19 09:48:49 · 258 阅读 · 0 评论 -
二进制中1的个数
题目输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。非负整数解法先判断二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时从右边数起的第二位被移到最右边了,再判断是不是1。这样每次移动一位,直到整个整数变成0为止。当输入一个负数时,会陷入死循环,因为负数右移一位,最高位会填充1。int NumberOf...原创 2019-03-20 14:21:19 · 272 阅读 · 0 评论 -
用O(1)时间删除链表结点
题目给定单向链表的头指针和一个结点指针,定义一个函数在o(1)时间删除该结点。思路 如果要删除的结点不是尾结点,我们要删除结点i,先把i的一个结点j的内容复制到i,然后把i的指针指向结点j的下一个结点。此时再删除结点j,其效果刚好是把结点i给删除了。 如果要删除的结点位于链表的尾部,我们从链表的头结点开始,顺序遍历得到该结点的前序结点,并完...原创 2019-04-01 09:17:17 · 170 阅读 · 0 评论 -
树的子结构--《剑指offer》面试题18
题目 输入两棵二叉树A和B,判断B是不是A的子结构。如图:A中有一部分子树的结构和B是一样的,因此B是A的子结构。思路 要查找树A中是否存在和树B结构一样的子树,分成两步:第一,在树A中找到和B的根结点的值一样的结点R;第二,判断树A中以R为根结点的子树是不是包含和树B一样的结构。 判断树A中以R为根结点的子树是不...原创 2019-04-10 14:02:09 · 409 阅读 · 0 评论 -
二叉树中和为某一值的路径 ----《剑指offer》面试题25
题目 输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。思路 当用前序遍历的方式访问到某一结点时,我们把结点添加到路径上,并累加该结点的值。如果该结点为叶结点并且路径中结点值的和刚好等于输入的整数,则当前的路径符合要求,将它打印出来。如果当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归...原创 2019-07-16 09:48:39 · 115 阅读 · 0 评论 -
二叉搜索树与双向链表 ----《剑指offer》面试题27
题目 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路 可以用分治的思想来解决该问题。如果要将一颗BST(二叉搜索树)转换成一个排序的双向链表,可以将BST简化的看成只有三个结点的树。根结点是BST的根结点,另外两个结点分别代表BST的左子树与又子树。同样又能将左子树与右子树细化成同样的结点。此时,只要懂得如何...原创 2019-07-18 10:34:02 · 103 阅读 · 0 评论 -
包含min函数的栈 ----《剑指offer》面试题21
题目定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)思路 用一个std::stack<std::pair<int,int>>表示这个栈, pair<int,int>中 first表示要插入的值,second表示当前栈中最小的元素。 这样每次栈顶元素的second的值...原创 2019-06-28 18:04:04 · 120 阅读 · 0 评论 -
从上往下打印二叉树 ----《剑指offer》面试题23
题目从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。思路代码#include <iostream>#include <queue>using namespace std;struct BinaryTreeNode{ int value; BinaryTreeNode* p_left; BinaryTree...原创 2019-07-08 14:54:40 · 136 阅读 · 0 评论 -
栈的压入、弹出序列 ----《剑指offer》面试题22
题目 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。解题思路 建立一个辅助栈,把输入的第一个序列中的数据依次压入该辅助栈,并按照第二个序列的顺序依次从该栈中弹出数字。...原创 2019-07-08 00:05:46 · 110 阅读 · 0 评论 -
反转链表--《剑指offer》面试题16
题目 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。思路 定义3个指针,分别指向当前遍历到的结点、它的前一个结点以及后一个结点。在调整结点 i 的m_pNext指针时,除了需要知道结点 i 本身之外,还需要 i 的前一个结点 h,因为我们需要把结点 i 的m_pNext指向结点 h。同时,我们还需要事先保存 i 的下...原创 2019-04-09 21:19:40 · 149 阅读 · 0 评论 -
链表中倒数第K个结点--《剑指offer》面试题15
题目 输入一个链表,输出该链表中倒数第k个结点。解决思路 定义两个指针。第一个指针从链表的开始遍历,向前走k-1步,第二个指针保持不动。从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个指针到达链表的尾结点时,第二个指针正好指向倒数第k个结点。代码#include <iostream&g...原创 2019-04-03 20:12:50 · 160 阅读 · 0 评论 -
顺时针打印矩阵----《剑指offer》面试题20
题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出第一个数字。如图:如果输入以下矩阵:思路 由于是以从外圈到内圈的顺序依次打印,我们可以把矩阵想象成若干个圈,每一次打印矩阵中的一个圈。如果以最外圈开始打印,那么每一圈开始打印的位置是从左上角开始的。如果矩阵的行数是rows,列数是columns。则左上角的坐标是(0,0),(1,1...原创 2019-04-12 15:05:39 · 173 阅读 · 0 评论