剑指offer题目汇总(三)
来源:互联网 发布:手机克隆软件 编辑:程序博客网 时间:2024/05/16 05:21
剑指offer 面试题 21-30
作者代码下载地址 https://github.com/zhedahht/CodingInterviewChinese2
面试题21:调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
// ====================方法一====================void ReorderOddEven_1(int *pData, unsigned int length){ if(pData == nullptr || length == 0) return; int *pBegin = pData; int *pEnd = pData + length - 1; while(pBegin < pEnd) { // 向后移动pBegin,直到它指向偶数 while(pBegin < pEnd && (*pBegin & 0x1) != 0) pBegin ++; // 向前移动pEnd,直到它指向奇数 while(pBegin < pEnd && (*pEnd & 0x1) == 0) pEnd --; if(pBegin < pEnd) { int temp = *pBegin; *pBegin = *pEnd; *pEnd = temp; } }}// ====================方法二====================void ReorderOddEven_2(int *pData, unsigned int length){ Reorder(pData, length, isEven);}void Reorder(int *pData, unsigned int length, bool (*func)(int)){ if(pData == nullptr || length == 0) return; int *pBegin = pData; int *pEnd = pData + length - 1; while(pBegin < pEnd) { // 向后移动pBegin while(pBegin < pEnd && !func(*pBegin)) pBegin ++; // 向前移动pEnd while(pBegin < pEnd && func(*pEnd)) pEnd --; if(pBegin < pEnd) { int temp = *pBegin; *pBegin = *pEnd; *pEnd = temp; } }}bool isEven(int n){ return (n & 1) == 0;}
面试题22:链表中倒数第k个结点
题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){ if(pListHead == nullptr || k == 0) return nullptr; ListNode *pAhead = pListHead; ListNode *pBehind = nullptr; for(unsigned int i = 0; i < k - 1; ++ i) { if(pAhead->m_pNext != nullptr) pAhead = pAhead->m_pNext; else { return nullptr; } } pBehind = pListHead; while(pAhead->m_pNext != nullptr) { pAhead = pAhead->m_pNext; pBehind = pBehind->m_pNext; } return pBehind;}
面试题23:链表中环的入口结点
题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,环的入口结点是结点3。
ListNode* MeetingNode(ListNode* pHead){ if(pHead == nullptr) return nullptr; ListNode* pSlow = pHead->m_pNext; if(pSlow == nullptr) return nullptr; ListNode* pFast = pSlow->m_pNext; while(pFast != nullptr && pSlow != nullptr) { if(pFast == pSlow) return pFast; pSlow = pSlow->m_pNext; pFast = pFast->m_pNext; if(pFast != nullptr) pFast = pFast->m_pNext; } return nullptr;}ListNode* EntryNodeOfLoop(ListNode* pHead){ ListNode* meetingNode = MeetingNode(pHead); if(meetingNode == nullptr) return nullptr; // 得到环中结点的数目 int nodesInLoop = 1; ListNode* pNode1 = meetingNode; while(pNode1->m_pNext != meetingNode) { pNode1 = pNode1->m_pNext; ++nodesInLoop; } // 先移动pNode1,次数为环中结点的数目 pNode1 = pHead; for(int i = 0; i < nodesInLoop; ++i) pNode1 = pNode1->m_pNext; // 再移动pNode1和pNode2 ListNode* pNode2 = pHead; while(pNode1 != pNode2) { pNode1 = pNode1->m_pNext; pNode2 = pNode2->m_pNext; } return pNode1;}
面试题24:反转链表
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
ListNode* ReverseList(ListNode* pHead){ ListNode* pReversedHead = nullptr; ListNode* pNode = pHead; ListNode* pPrev = nullptr; while(pNode != nullptr) { ListNode* pNext = pNode->m_pNext; if(pNext == nullptr) pReversedHead = pNode; pNode->m_pNext = pPrev; pPrev = pNode; pNode = pNext; } return pReversedHead;}
面试题25:合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图3.11中的链表1和链表2,则合并之后的升序链表如链表3所示。
ListNode* Merge(ListNode* pHead1, ListNode* pHead2){ if(pHead1 == nullptr) return pHead2; else if(pHead2 == nullptr) return pHead1; ListNode* pMergedHead = nullptr; if(pHead1->m_nValue < pHead2->m_nValue) { pMergedHead = pHead1; pMergedHead->m_pNext = Merge(pHead1->m_pNext, pHead2); } else { pMergedHead = pHead2; pMergedHead->m_pNext = Merge(pHead1, pHead2->m_pNext); } return pMergedHead;}
面试题26:树的子结构
题目:输入两棵二叉树A和B,判断B是不是A的子结构。
struct BinaryTreeNode{ double m_dbValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;};bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);bool Equal(double num1, double num2);bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2){ bool result = false; if(pRoot1 != nullptr && pRoot2 != nullptr) { if(Equal(pRoot1->m_dbValue, pRoot2->m_dbValue)) result = DoesTree1HaveTree2(pRoot1, pRoot2); if(!result) result = HasSubtree(pRoot1->m_pLeft, pRoot2); if(!result) result = HasSubtree(pRoot1->m_pRight, pRoot2); } return result;}bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2){ if(pRoot2 == nullptr) return true; if(pRoot1 == nullptr) return false; if(!Equal(pRoot1->m_dbValue, pRoot2->m_dbValue)) return false; return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) && DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);}bool Equal(double num1, double num2){ if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001)) return true; else return false;}
面试题27:二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
void MirrorRecursively(BinaryTreeNode *pNode){ if((pNode == nullptr) || (pNode->m_pLeft == nullptr && pNode->m_pRight)) return; BinaryTreeNode *pTemp = pNode->m_pLeft; pNode->m_pLeft = pNode->m_pRight; pNode->m_pRight = pTemp; if(pNode->m_pLeft) MirrorRecursively(pNode->m_pLeft); if(pNode->m_pRight) MirrorRecursively(pNode->m_pRight);}void MirrorIteratively(BinaryTreeNode* pRoot){ if(pRoot == nullptr) return; std::stack<BinaryTreeNode*> stackTreeNode; stackTreeNode.push(pRoot); while(stackTreeNode.size() > 0) { BinaryTreeNode *pNode = stackTreeNode.top(); stackTreeNode.pop(); BinaryTreeNode *pTemp = pNode->m_pLeft; pNode->m_pLeft = pNode->m_pRight; pNode->m_pRight = pTemp; if(pNode->m_pLeft) stackTreeNode.push(pNode->m_pLeft); if(pNode->m_pRight) stackTreeNode.push(pNode->m_pRight); }}
面试题28:对称的二叉树
题目:请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和
它的镜像一样,那么它是对称的。
bool isSymmetrical(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);bool isSymmetrical(BinaryTreeNode* pRoot){ return isSymmetrical(pRoot, pRoot);}bool isSymmetrical(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2){ if(pRoot1 == nullptr && pRoot2 == nullptr) return true; if(pRoot1 == nullptr || pRoot2 == nullptr) return false; if(pRoot1->m_nValue != pRoot2->m_nValue) return false; return isSymmetrical(pRoot1->m_pLeft, pRoot2->m_pRight) && isSymmetrical(pRoot1->m_pRight, pRoot2->m_pLeft);}
面试题29:顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
void PrintMatrixInCircle(int** numbers, int columns, int rows, int start);void printNumber(int number);void PrintMatrixClockwisely(int** numbers, int columns, int rows){ if(numbers == nullptr || columns <= 0 || rows <= 0) return; int start = 0; while(columns > start * 2 && rows > start * 2) { PrintMatrixInCircle(numbers, columns, rows, start); ++start; }}void PrintMatrixInCircle(int** numbers, int columns, int rows, int start){ int endX = columns - 1 - start; int endY = rows - 1 - start; // 从左到右打印一行 for(int i = start; i <= endX; ++i) { int number = numbers[start][i]; printNumber(number); } // 从上到下打印一列 if(start < endY) { for(int i = start + 1; i <= endY; ++i) { int number = numbers[i][endX]; printNumber(number); } } // 从右到左打印一行 if(start < endX && start < endY) { for(int i = endX - 1; i >= start; --i) { int number = numbers[endY][i]; printNumber(number); } } // 从下到上打印一行 if(start < endX && start < endY - 1) { for(int i = endY - 1; i >= start + 1; --i) { int number = numbers[i][start]; printNumber(number); } }}void printNumber(int number){ printf("%d\t", number);}
面试题30:包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。
template <typename T> class StackWithMin{public: StackWithMin() {} virtual ~StackWithMin() {} T& top(); const T& top() const; void push(const T& value); void pop(); const T& min() const; bool empty() const; size_t size() const;private: std::stack<T> m_data; // 数据栈,存放栈的所有元素 std::stack<T> m_min; // 辅助栈,存放栈的最小元素};template <typename T> void StackWithMin<T>::push(const T& value){ // 把新元素添加到辅助栈 m_data.push(value); // 当新元素比之前的最小元素小时,把新元素插入辅助栈里; // 否则把之前的最小元素重复插入辅助栈里 if(m_min.size() == 0 || value < m_min.top()) m_min.push(value); else m_min.push(m_min.top());}template <typename T> void StackWithMin<T>::pop(){ assert(m_data.size() > 0 && m_min.size() > 0); m_data.pop(); m_min.pop();}template <typename T> const T& StackWithMin<T>::min() const{ assert(m_data.size() > 0 && m_min.size() > 0); return m_min.top();}template <typename T> T& StackWithMin<T>::top(){ return m_data.top();}template <typename T> const T& StackWithMin<T>::top() const{ return m_data.top();}template <typename T> bool StackWithMin<T>::empty() const{ return m_data.empty();}template <typename T> size_t StackWithMin<T>::size() const{ return m_data.size();}
0 0
- 剑指offer题目汇总(三)
- 剑指offer题目汇总(一)
- 剑指offer题目汇总(二)
- 剑指offer题目思想汇总
- 剑指offer 面试题题目汇总
- [面试算法] 剑指Offer题目代码汇总
- 剑指offer--DP类题目汇总
- 剑指offer编程题目汇总(更新中。。)
- 剑指offer算法编程题目部分汇总(解法略)
- 牛客网做题总结:剑指offer中题目,java版三
- 剑指Offer题目JAVA版思路与代码(三)
- 计算机网络---基础题目汇总三
- 操作系统---基础题目汇总三
- 机器学习题目汇总三
- 剑指offer题目集
- 剑指offer题目记录
- 剑指offer题目概括
- 剑指offer题目
- 集成Tinker后的坑 , noclassdeffounderror异常
- jsp 乱码处理
- Spring入门——Bean管理的注解实现及例子
- JS实现图片翻书效果
- 为什么做AI的都选Python?
- 剑指offer题目汇总(三)
- WebRTC详解
- Android Studio入门到精通
- eclipse
- setTimeout参数传递obj对象时,循环调用解决办法
- 100亿数据1万属性数据架构设计
- Javascript的简单测试环境
- android群英传 学习笔记--第一篇
- Apache Zeppelin ——活灵活现的大数据