剑指offer
xupeng1644
道阻且长,行则将至!
展开
-
47. 不用加减乘除做加法(C++版本)
题目:写一个函数,求两个整数之和,要求再函数体内不得使用+、-、x、/四则运算符号。代码实现:在这里插入代码片原创 2020-01-07 10:58:49 · 1297 阅读 · 0 评论 -
46. 求1+2+3+...+n(C++实现)
题目:求1+2+3+…+n,要求不能使用乘除法、for、while、else、switch、case等关键字及条件判断语句(A?B:C)。代码实现:1.构造函数法class OneClass{public: OneClass() { ++m_objectTotalCount; m_totalSum += m_objectTotalCount; } static ...原创 2019-12-31 13:10:50 · 1919 阅读 · 0 评论 -
45. 圆圈中最后剩下的数字
题目:0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆圈里面剩下的最后一个数字。代码实现:int GetLastRemainData(int n, int m){ if (n < 2 || m < 1) return -1; std::list<int> datas; for (int curData...原创 2019-12-30 13:29:50 · 1281 阅读 · 0 评论 -
44. 扑克牌的顺子(C++版本)
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1, J为11, Q为12, K为13, 而大王、小王可以看成任意数字。实现代码:bool IsContinusCards(int* pData, int size){ if (nullptr == pData || size != 5) return false; std::sor...原创 2019-12-30 13:08:26 · 1894 阅读 · 0 评论 -
42.翻转单词顺序 VS 左旋转字符串(C++版本)
题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字符一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。实现代码:void Reverse(char* pBegin, char* pEnd){ if (nullptr == pBegin || nullptr == pEnd) ret...原创 2019-12-26 16:04:35 · 1420 阅读 · 0 评论 -
41. 和为s的两个数字VS和为s的连续正数序列(C++版本)
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得他们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。实现代码:bool GetTwoNumWithDestSum(int* pData, int size, int destData, int& num1, int& num2){ if (nullptr == pData || size &...原创 2019-12-26 13:52:09 · 1353 阅读 · 0 评论 -
40. 数组中只出现一次的数字(C++版本)
实现代码:int GetIdxOfFirst1AtData(int curData){ int curIdx = 0; const int maxIdx = 32; while (curIdx != maxIdx) { if (0 == curData & 0x01) return curIdx; ++curIdx; curData >> 1; }...原创 2019-12-25 14:45:42 · 1699 阅读 · 0 评论 -
39. (附加)二叉树是不是平衡二叉树(C++版本)
基础版本:int GetBinaryTreeDepth(BinaryTreeNode* pRoot){ if (nullptr == pRoot) return 0; int leftTreeDepth = pRoot->pLeft != nullptr ? GetBinaryTreeDepth(pRoot->pLeft) : 0; int rightTreeDepth =...原创 2019-12-25 11:10:10 · 1255 阅读 · 0 评论 -
39. 二叉树的深度(C++版本)
实现代码:int GetBinaryTreeDepth(BinaryTreeNode* pRoot){ if (nullptr == pRoot) return 0; int leftTreeDepth = pRoot->pLeft != nullptr ? GetBinaryTreeDepth(pRoot->pLeft) : 0; int rightTreeDepth =...原创 2019-12-25 10:44:11 · 1246 阅读 · 0 评论 -
38. 数字在排序数组中出现的次数(C++版本)
实现代码:int GetFirstPosOfDestData(int* pData, int size, int destData, int begin, int end){ if (nullptr == pData || size < 1) return -1; if (begin > end) return -1; // 未找到 int middle = begin +...原创 2019-12-25 09:55:54 · 1370 阅读 · 0 评论 -
37. 两个链表的第一个公共节点(C++版本)
实现代码:int GetListLength(ListNode* pHead){ if (nullptr == pHead) return 0; int listLen = 0; ListNode* pCurNode = pHead; while (pCurNode != nullptr) { ++listLen; pCurNode = pCurNode->pNext...原创 2019-12-24 19:42:46 · 1345 阅读 · 0 评论 -
35. 第一个只出现一次的字符(C++版本)
char GetFirstNotRepeatChar(char* pData){ if (nullptr == pData) return '\0'; const int TEMP_DATA_SIZE = 256; int tempDatas[TEMP_DATA_SIZE]; // 用来存储字符出现的次数 std::memset(tempDatas, 0, sizeof(int) * ...原创 2019-12-23 17:50:41 · 1305 阅读 · 0 评论 -
34. 丑数(C++版本)
基础版本:bool IsUglyNum(int64_t data){ int64_t curData = data; while (curData % 2 == 0) curData /= 2; while (curData % 3 == 0) curData /= 3; while (curData % 5 == 0) curData /= 5; return 1 == curDa...原创 2019-12-23 15:33:36 · 1431 阅读 · 0 评论 -
33. 把数组排成最小的数(C++版本)
实现要点:将数组按照特定规则排序,依次组合起来就是最小的数。排序规则为 A + B < B + A时为true。代码实现:std::string GetMinNumber(const std::vector<int>& datas){ if (datas.empty()) return ""; std::vector<std::string> ...原创 2019-12-23 11:28:24 · 1543 阅读 · 0 评论 -
31. 连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。实现代码:int GetConsequenceGreatestSum(int* pData, int size){ if (nullptr == pData || size <= 0) return INT_MIN; // INIT_MIN...原创 2020-03-01 12:19:51 · 1331 阅读 · 0 评论 -
30. 最小的K个数(C++版本)
基于Partition的方法:int Partition(int* pData, int begin, int end){ int pivot = pData[begin]; // 以第一个元素作为基准值 int left = begin; int right = end; while (left < right) { while (left < right &...原创 2019-12-19 16:21:28 · 1440 阅读 · 0 评论 -
29. 数组中出现超过一半的数字(C++版本)
两种方法,找到具体值之后,均没有进行值得判断(是否出现次数超过一半)。1. 中位数法int Partition(int* pData, int begin, int end){ int pivot = pData[begin]; // 以第一个元素作为基准值 int left = begin; int right = end; while (left < right) {...原创 2019-12-19 15:15:23 · 1479 阅读 · 1 评论 -
28. (附加)八皇后问题(C++版本)
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?使用回溯法,总共92种摆法。判断当前行destRow的赋值是否满足条件:(假定其他行为curRow)不在同一行:肯定不在同一行,因为是按照行来进行赋值的。不在同一列:pData[curRow] != pData[destRow]不在对角线上:std::abs(pDa...原创 2019-11-26 12:53:22 · 1444 阅读 · 0 评论 -
28. (附加)字符串的组合(C++版本)
实现代码:加粗样式void Conbination(char* pData, char* pDestData, int begin, int end, int curIdx, int remainCount){ if (0 == remainCount) { std::cout << pDestData << std::endl; return; }...原创 2019-12-18 17:56:29 · 1792 阅读 · 0 评论 -
28. 字符串的排列(C++版本)
实现代码:void Permutation(char* pInitData, char* pCurData){ if ('\0' == *pCurData) // 已经处理完毕 { std::cout << pInitData << std::endl; return; } for (char* pData = pCurData; *pData != ...原创 2019-12-18 16:44:26 · 1247 阅读 · 0 评论 -
27. 二叉搜索树与双向链表(C++版本)
题目:输入一颗二叉搜索数,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。二叉树节点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;}实现代码:void ConvertNode(Binar...原创 2020-02-29 21:56:40 · 1652 阅读 · 0 评论 -
26. 复杂链表的复制
题目:请实现函数ComplexListNode* Clone(ComplexListNode* pHead);复制一个复杂链表。在复杂链表中,每个节点除了有一个m_pNext指针指向下一个节点外,还有一个m_pSibling指向链表中的任意节点或者NULL。节点的C++定义如下:struct ComplexListNode{ int m_nValue; ComplexListNode...原创 2020-03-01 11:40:50 · 1324 阅读 · 0 评论 -
25. (附加)二叉树的所有路径(C++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)注意点:找到的是从根节点到叶子节点的所有路径。实现代码:void FindPath(BinaryTreeNode* pRoot, int destData){ if (nullptr == pRoot) return; std::vector<int> paths; FindPath(pRoot, paths,...原创 2019-12-17 13:43:26 · 1386 阅读 · 0 评论 -
25. 二叉树中和为某一个值的路径(C++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)注意点:找到的是从根节点到叶子节点的路径。实现代码:void PrintData(std::vector<int>& paths){ for (auto& curData : paths) std::cout << curData << " "; std::cout <...原创 2019-12-17 13:21:05 · 1450 阅读 · 0 评论 -
24. (附加)二叉搜索树的前续遍历序列(c++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)注意点:假设左子树小于等于根节点,右子树大于根节点。实现代码:bool IsPreOrder(int* pData, int begin, int end){ if (nullptr == pData || begin < 0 || end < 0) return false; if (begin > end...原创 2019-12-17 11:36:48 · 1335 阅读 · 0 评论 -
24. 二叉搜索树的后续遍历序列(c++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)注意点:实现代码:bool IsPostOrder(int* pData, int begin, int end){ if (nullptr == pData) return false; if (begin > end) return false; if (begin == end) return true;// 只有...原创 2019-12-16 14:34:01 · 1083 阅读 · 0 评论 -
23. 从上往下打印二叉树[层序遍历](C++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)实现代码:void LevelOrderTraverse(BinaryTreeNode* pRoot){ if (nullptr == pRoot) return; std::queue<BinaryTreeNode*> datas; datas.push(pRoot); while (!datas.empty...原创 2019-12-14 15:02:49 · 1276 阅读 · 0 评论 -
22. 栈的压入、弹出队列(C++版本)
实现思路:实现过程需要使用一个栈。如果当前栈为空或者栈顶元素不等于弹出队列中的当前元素,压入压入队列中的当前元素,如果此时压入队列中已经没有元素,说明该弹出队列不满足条件。如果栈顶元素等于弹出队列中的当前元素,弹出栈顶,弹出队列待处理元素后移一位。循环处理,直到处理完弹出队列元素。注意点:因为实现代码中使用的是数组指针,所以需要调用方确保两个队列元素个数相等。实现代码:bool ...原创 2019-12-14 14:27:15 · 1646 阅读 · 0 评论 -
21. 包含min函数的栈(C++版本)
实现思路:用一个栈(数据栈)保存数据,另外一个栈(最小值栈)保存最小值。每次Push时,将数据直接压入数据栈。然后将数据根据条件压入到最小值栈,如果最小值栈为空,直接压入最小值栈。如果数据比最小值栈栈顶元素小,则将其压入最小值栈。否则压入最小值栈栈顶元素。每次Pop时,将数据栈和最小值栈的栈顶都进行pop。实现代码:头文件StackWithMin.hclass StackWithMin...原创 2019-12-14 11:07:27 · 1414 阅读 · 0 评论 -
20. 顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: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代码实现:void PrintMatrixInCircle(int** num...原创 2020-02-28 15:50:53 · 1296 阅读 · 0 评论 -
19. 镜像二叉树(C++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)循环实现:void MirrorBinaryTree(BinaryTreeNode* pRoot){ if (nullptr == pRoot) return; std::queue<BinaryTreeNode*> datas; datas.push(pRoot); while (!datas.empty())...原创 2019-12-11 13:01:28 · 1379 阅读 · 0 评论 -
18. 树的子结构(C++版本)
使用二叉树的相关定义及函数在:二叉树最小结构(C++版本)实现原理:使用两个指针pFrontNode、pBackNode,它们都指向头节点。先让pFrontNode向前走k-1步,然后两个指针同时向前走。当pFrontNode指向最后一个节点时,pBackNode指向的节点即为倒数第k个节点(因为两个指针的距离位k-1)。...原创 2019-12-11 12:39:36 · 1458 阅读 · 0 评论 -
17. 合并两个排序的链表(C++版本)
使用的链表相关定义及函数在:链表最小结构(C++版本)假设链表本身是升序排序的。递归实现:ListNode* MergeList(ListNode* pNode1, ListNode* pNode2){ if (nullptr == pNode1) return pNode2; if (nullptr == pNode2) return pNode1; ListNode* pMer...原创 2019-12-05 16:05:12 · 1507 阅读 · 0 评论 -
16. 反转链表(C++版本)
使用的链表相关定义及函数在:链表最小结构(C++版本)循环实现:void ReverseList(MyList& myList){ if (nullptr == myList.pHead) return; ListNode* pCurNode = myList.pHead; ListNode* pNextNode = nullptr; ListNode* pPrevNode...原创 2019-12-05 13:49:02 · 1325 阅读 · 0 评论 -
15. (附加)链表是否有环(C++版本)
使用的链表相关定义及函数在:链表最小结构(C++版本)实现思路:使用两个指针pFrontNode、pBackNode,它们都指向头节点。每次让pFrontNode向前走2步,pBackNode向前走1步。如果某次走完后,pFrontNode等于pBackNode,链表有环。如果pFrontNode已经为空,链表无环。实现代码:bool DoesListHasCircle(const ...原创 2019-12-05 13:07:12 · 1332 阅读 · 0 评论 -
15. (附加)链表中间节点(C++版本)
使用的链表相关定义及函数在:链表最小结构(C++版本)实现原理:使用两个指针pFrontNode、pBackNode,它们都指向头节点。每次让pFrontNode向前走2步,pBackNode向前走1步。直到pFrontNode走到最后一个节点停止,pBackNode所指的即为中间节点。实现代码:ListNode* GetMiddleNodeFromTail(const MyList&...原创 2019-12-05 11:58:04 · 1253 阅读 · 0 评论 -
15. 链表中倒数第k个节点(C++版本)
使用的链表相关定义及函数在:链表最小结构(C++版本)实现原理:使用两个指针pFrontNode、pBackNode,它们都指向头节点。先让pFrontNode向前走k-1步,然后两个指针同时向前走。当pFrontNode指向最后一个节点时,pBackNode指向的节点即为倒数第k个节点(因为两个指针的距离位k-1)。实现代码:ListNode* GetNthNodeFromTail(...原创 2019-12-04 19:47:41 · 1345 阅读 · 0 评论 -
14. 调整数组顺序是奇数位于偶数前(C++版本)
常规方法:void ReorderArray(int pData[] ,unsigned int size){ if (nullptr == pData || 0 == size) return; int begin = 0; int end = size - 1; while (begin < end) { while (begin < end &&am...原创 2019-12-04 13:28:20 · 1488 阅读 · 0 评论 -
13. 在O(1)时间删除链表节点(C++版本)
使用的链表相关定义及函数在:链表最小结构(C++版本)前置条件:待删除节点pRemoveNode一定在链表myList中。void RemoveNodeFromList(MyList& myList, ListNode* pRemoveNode){ if (nullptr == pRemoveNode) return; if (pRemoveNode->pNext != ...原创 2019-12-03 20:50:46 · 1402 阅读 · 0 评论 -
12. 打印1到最大的n位数(C++版本)
递归版本:void PrintData(char* pData, int size){ // 从第一个不为'0'的位置开始输出 for (int idx = 0; idx < size; ++idx) { if (pData[idx] == '0') continue; std::cout << (pData + idx) << std::endl;...原创 2019-12-03 13:58:39 · 1449 阅读 · 0 评论