[剑指offer]
唐火
开始人工智能之路了!!!
展开
-
[剑指offer]面试题45:圆圈中最后剩下的数字
面试题45:圆圈中最后剩下的数字题目:0,1,…,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。❖ 经典的解法,用环形链表模拟圆圈代码如下:#include <iostream>#include <list>using namespace std;int LastRemaining(unsigned int n, unsigned int m){ if (n < 1 || m < 1) re原创 2021-05-21 21:14:11 · 116 阅读 · 0 评论 -
[剑指offer]面试题48:不能被继承的类
面试题48:不能被继承的类题目:用C++设计一个不能被继承的类。❖ 常规的解法:把构造函数设为私有函数很多人都能够想到,在 C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于调用构造函数、析构函数而导致编译错误。可是这个类型的构造函数和析构函数都是私有函数,我们怎样才能得到该类型的实例呢?我们可以通过定义公有的静态函数来创建和释放类的实例。基于原创 2021-05-21 13:26:35 · 165 阅读 · 0 评论 -
[剑指offer]面试题47:不用加减乘除做加法
面试题47:不用加减乘除做加法题目:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、×、÷四则运算符号。代码如下:int add(int num1, int num2){ int sum, carry; do { sum = (num1 ^ num2); carry = (num1 & num2) << 1; num1 = sum; num2 = carry; } while (num2 != 0); return num1;}测试用原创 2021-05-21 13:13:22 · 95 阅读 · 0 评论 -
[剑指offer]面试题42:翻转单词顺序 VS左旋转字符串
面试题42:翻转单词顺序 VS左旋转字符串题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student.a am I"。代码如下:void Reverse(char *pBegin, char *pEnd){ if (pBegin == nullptr || pEnd == nullptr) return; while (pBegin < pEnd) { ch原创 2021-05-20 13:37:15 · 128 阅读 · 0 评论 -
[剑指offer]面试题41:和为s的两个数字VS和为s的连续正数序列
面试题41:和为s的两个数字VS和为s的连续正数序列题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。代码如下:bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2){ bool found = false; if (length < 1 || num1 == nullptr || num2 == nullpt原创 2021-05-20 13:14:51 · 92 阅读 · 0 评论 -
[剑指offer]面试题37:两个链表的第一个公共结点
面试题37:两个链表的第一个公共结点题目:输入两个链表,找出它们的第一个公共结点。链表结点定义如下:struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {}};思路:两个链表长度分别为L1+C、L2+C, C为公共部分的长度, 第一个人走了L1+C步后,回到第二个人起点走L2步;第2个人走了L2+C步后,回到第一个人起点走L1步。 当两个人走的步数都为L1+L2+C时就两个家伙就相爱原创 2021-05-20 12:40:34 · 79 阅读 · 0 评论 -
[剑指offer]面试题35:第一个只出现一次的字符
面试题35:第一个只出现一次的字符题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出’b’。代码如下:char FirstNotRepeatingChar(char *pString){ if (pString == nullptr) return '\0'; const int tableSize = 256; unsigned int hashTable[tableSize]; for (unsigned int i = 0; i < tableSiz原创 2021-05-20 12:33:33 · 102 阅读 · 2 评论 -
[剑指offer]面试题34:丑数
面试题34:丑数题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。❖ 逐个判断每个整数是不是丑数的解法,直观但不够高效代码如下:bool IsUgly(int number){ while (number % 2 == 0) number /= 2; while (number % 3 == 0) number /= 3; while (numb原创 2021-05-20 12:19:21 · 348 阅读 · 0 评论 -
[剑指offer]面试题28:字符串的排列
面试题28:字符串的排列题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。思路:这是一个典型的递归问题,考虑如何将复杂问题分解成简单问题,最后通过递归解决。我们肯定有这样的经验,自己在写abc的全排列的时候,肯定会想首先确定第一个字符,然后考虑后面有什么排列,比如确定第一个字符为a,那么剩下的b和c有两种排列,分别是bc和cb,那么以a开头的字符串有abc,acb这两种排列。这就是原创 2021-05-20 12:19:15 · 83 阅读 · 0 评论 -
[剑指offer]面试题31:连续子数组的最大和
面试题31:连续子数组的最大和题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。❖ 解法一:举例分析数组的规律代码如下:bool flag = false;int FindGreatestSumOfSubArray(int *pDate, int nLength){ if ((pDate == nullptr) || (nLength <= 0)) { flag = true; retu原创 2021-05-20 12:19:18 · 86 阅读 · 0 评论 -
[剑指offer]面试题26:复杂链表的复制
面试题26:复杂链表的复制题目:请实现函数ComplexListNodeClone(ComplexListNodepHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling 指向链表中的任意结点或者NULL。结点的C++定义如下:struct ComplexListNode{ int value; ComplexListNode * next; ComplexListNode * sibling;};第一步:代码如原创 2021-05-19 19:36:55 · 107 阅读 · 0 评论 -
[剑指offer]面试题23:从上往下打印二叉树
面试题23:从上往下打印二叉树题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。例如输入图4.5中的二叉树,则依次打印出8、6、10、5、7、9、11。二叉树结点的定义如下:struct BinaryTreeNode{ int value; BinaryTreeNode *lchild; BinaryTreeNode *rchild;};思路:每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的原创 2021-05-19 18:57:52 · 72 阅读 · 0 评论 -
[剑指offer]面试题22:栈的压入、弹出序列
面试题22:栈的压入、弹出序列题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5 是某栈的压栈序列,序列4、5、3、2、1 是该压栈序列对应的一个弹出序列,但 4、3、5、1、2 就不可能是该压栈序列的弹出序列。压栈序列为1、2、3、4、5,弹出序列4、5、3、2、1对应的压栈和弹出过程一个压入顺序为1、2、3、4、5的栈没有一个弹出序列为4、3、5、1、2规律:如果下一个弹出的数字刚好是栈顶数字,原创 2021-05-19 18:43:30 · 145 阅读 · 0 评论 -
[剑指offer]面试题21:包含min函数的栈
面试题21:包含min函数的栈题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。栈内压入3、4、2、1之后接连两次弹出栈顶数字再压入0时,数据栈、辅助栈和最小值的状态代码如下:#include <iostream>#include <stack>#include <assert.h>using namespace std;template<typenam原创 2021-05-19 13:48:24 · 95 阅读 · 0 评论 -
[剑指offer]面试题19:二叉树的镜像
面试题19:二叉树的镜像题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。二叉树结点的定义如下:struct BinaryTreeNode{ int value; BinaryTreeNode *lchild; BinaryTreeNode *rchild;};求一棵树的镜像的过程:我们先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点。当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。代码如下:void MirrorRecursively(B原创 2021-05-19 13:34:02 · 93 阅读 · 2 评论 -
[剑指offer]面试题18:树的子结构
面试题18:树的子结构题目:输入两棵二叉树A和B,判断B是不是A的子结构。二叉树结点的定义如下:struct BinaryTreeNode{ int value; BinaryTreeNode *lchild; BinaryTreeNode *rchild;};代码如下:bool HasSubtree(BinaryTreeNode *pRoot1, BinaryTreeNode *pRoot2){ bool res = false; if (pRoot1 != nullptr &a原创 2021-05-19 13:14:44 · 61 阅读 · 0 评论 -
[剑指offer]面试题17:合并两个排序的链表
面试题17:合并两个排序的链表题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图3.7中的链表1和链表2,则合并之后的升序链表如链表3所示。链表结点定义如下:struct ListNode{ int value; ListNode *next;};代码如下:ListNode *Merge(ListNode *pHead1, ListNode *pHead2){ if (pHead1 == nullptr) return pHead2; el原创 2021-05-19 12:54:37 · 111 阅读 · 0 评论 -
[剑指offer]面试题16:反转链表
面试题16:反转链表题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。链表结点定义如下:struct ListNode{ int value; ListNode *next;};代码如下:ListNode *ReverseList(ListNode *pHead){ ListNode *pReversedHead = nullptr; ListNode *pNode = pHead; ListNode *pPrev = nullptr; while (原创 2021-05-19 12:45:59 · 89 阅读 · 0 评论 -
[剑指offer]面试题15:链表中倒数第k个结点
面试题15:链表中倒数第k个结点题目:输入一个链表,输出该链表中倒数第 k 个结点。为了符合大多数人的习惯,本题从1 开始计数,即链表的尾结点是倒数第1 个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。链表结点定义如下:struct ListNode{ int value; ListNode *next;};为了实现只遍历链表一次就能找到倒数第 k 个结点,我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前原创 2021-05-19 00:24:11 · 108 阅读 · 0 评论 -
[剑指offer]面试题13:在O(1)时间删除链表结点
面试题13:在O(1)时间删除链表结点题目:给定单向链表的头指针和一个结点指针,定义一个函数在 O(1)时间删除该结点。链表结点与函数的定义如下:struct ListNode{ int value; ListNode *next;};void DeleteNode(ListNode ** pListHead, ListNode *pToBeDeleted);代码如下:struct ListNode{ int value; ListNode *next;};void Del原创 2021-05-18 23:54:49 · 101 阅读 · 0 评论 -
[剑指offer]面试题10:二进制中1的个数
面试题10:二进制中1的个数题目:请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。❖ 可能引起死循环的解法代码如下:int CountNumbers(int n){ int count = 0; while (n) { if (n & 1) count++; n = n >> 1; } return count;}面试官看了代码之后可能会问:把整数右移一位和把整数除原创 2021-05-18 23:33:58 · 97 阅读 · 0 评论 -
[剑指offer]面试题9:斐波那契数列
面试题9:斐波那契数列题目一:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下:❖ 效率很低的解法,挑剔的面试官不会喜欢代码如下:long long fib(unsigned int n){ if (n <= 0) return 0; if (n == 1) return 1; return fib(n - 1) + fib(n - 2);}❖ 面试官期待的实用解法其实改进的方法并不复杂。上述递归代码之所以慢是因为重复的计算太多,我们只原创 2021-05-18 22:41:08 · 134 阅读 · 0 评论 -
[剑指offer]面试题8:旋转数组的最小数字
面试题8:旋转数组的最小数字题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。在数组{3,4,5,1,2}中查找最小值的过程:#include <iostream>using namespace std;int Min(int *numbers, int length){ if (numbers == nullpt原创 2021-05-18 22:28:01 · 108 阅读 · 0 评论 -
[剑指offer]面试题7:用两个栈实现队列
面试题7:用两个栈实现队列题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。用两个栈模拟一个队列的操作:代码如下:#include <iostream>#include <stack>using namespace std;template <typename T>class CQueue{public: CQueue(void);原创 2021-05-18 22:03:28 · 111 阅读 · 0 评论 -
[剑指offer]面试题5:从尾到头打印链表
面试题5:从尾到头打印链表题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表结点定义如下:struct ListNode{ int m_nKey; ListNode *m_pNext;};通常打印是一个只读操作,我们不希望打印时修改内容。假设面试官也要求这个题目不能改变链表的结构。接下来我们想到解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后原创 2021-05-18 21:23:08 · 84 阅读 · 0 评论 -
[剑指offer]面试题4:替换空格
面试题4:替换空格题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”,则输出“We%20are%20happy.”。❖ 时间复杂度为O(n2)的解法,不足以拿到Offer最直观的做法是从头到尾扫描字符串,每一次碰到空格字符的时候做替换。由于是把1个字符替换成3个字符,我们必须要把空格后面所有的字符都后移两个字节,否则就有两个字符被覆盖了。代码如下:#include <iostream>using namespace std;//le原创 2021-05-18 21:10:09 · 100 阅读 · 2 评论 -
[剑指offer]面试题3:二维数组中的查找
面试题3:二维数组中的查找题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。解题思路:首先选取数组中右上角的数字。如果该数字等于要查找的数字,查找过程结束;如果该数字大于要查找的数字,剔除这个数字所在的列;如果该数字小于要查找的数字,剔除这个数字所在的行。代码如下:从矩阵的右上角开始找:#include <iostream>using namespace std原创 2021-05-18 13:39:51 · 114 阅读 · 2 评论 -
[剑指offer]面试题1:赋值运算符函数
面试题1:赋值运算符函数题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数。class CMyString{public: CMyString(char *pData = nullptr); CMyString(const CMyString &str); ~CMyString(void);private: char *m_pDate;};经典解法,适用初级程序员:CMyString & CMyString::operator=(const C原创 2021-05-18 13:07:16 · 111 阅读 · 0 评论