剑指offer--堆、栈,队列、链表题目总结
来源:互联网 发布:计算机算法有几个 编辑:程序博客网 时间:2024/05/17 06:34
剑指offer
1.链表,添加链表
struct ListNode{ int val; ListNode* pNext;}void AddToTail(ListNode**pHead, int value){ if()}删除链表
void RemoveNode(ListNode**pHead,int value){ if(pHead==NULL||*pHead==NULL) return; ListNode* pDelete=NULL; if(*pHead->val==value) { pDelete=*pHead; *pHead=(*phead)->pNext; } else{ ListNode* pNode=*pHead; while(pNode->pNext!=NUll&&PNode->pNext->pval==value) { pDelete=pNode->pNext; pNode->pNext=pNode->pNext->pNext; } } if(pDelete!=NULL) { delete pDelete; pDelete=NULL;}
2. 从头到尾打印链表
*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) :* val(x), next(NULL) {* }* };*///输入一个链表,从尾到头打印链表每个节点的值。class Solution {public: vector<int> printListFromTailToHead(ListNode* head) { stack<ListNode*> S; ListNode* cur=head; while(cur) { S.push(cur); cur=cur->next; } vector<int>ans; while(!S.empty()) { cur=S.top(); S.pop(); ans.pushback(cur->val); } return ans; }};
3.在o(1)的时间内删除链表
/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*//*在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 因为相同的结点全部都要删除,设置三个指针,一个指向当前结点,一个指向前一结点,一个指向下一结点,一旦遇到当前结点等于下一结点的情况, 那么就一直移动,直到遇到下一个结点不同的状况,再将前一个结点指向此时结点的位置。*/class Solution {public: ListNode* deleteDuplication(ListNode* pHead) {if(!pHead) return; ListNode* pPreNode=NULL; ListNode* pNode=pHead; while(pNode!=NULL) { ListNode* pNext=pNode->next; bool needDelete=false; if(pNext!=NULL&&pNode->val==pNext->val) needDelete=true; if(!needDelete) { pPreNode = pNode; pNode = pNode->next; } else { int value = pNode->val; ListNode *pToBeDel = pNode; while(pToBeDel!= NULL && pToBeDel->val == value) { pNextNode = pToBeDel->next; delete pToBeDel; pToBeDel = NULL; pToBeDel = pNextNode; } if(pPreNode==NULL) pHead = pNextNode; else pPreNode->next = pNextNode; pNode = pNextNode; } } return pHead; }};
4.链表的倒数第k个节点
一个指针先往前走k-1步,然后另外一个指针才开始走,当第一个指针走到尾部了,那么第二个指针正好指向了倒数第k个结点
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if(pListHead==nullptr || k==0) return nullptr; ListNode *first = pListHead; for(int i = 1;i<k;i++) { first = first->next; if(first==nullptr) return nullptr; } ListNode *second = pListHead; while(first->next) { first = first->next; second = second->next; } return second; }};
5.反转链表
输入一个链表,反转链表后,输出链表的所有元素。
保存新的前一结点,当前结点和下一结点三个指针,只要下一结点为空,那么我们就到了原本结点的尾部,这时正是新链表的头部
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public: ListNode* ReverseList(ListNode* pHead) { if(pHead==nullptr) return nullptr; ListNode *pNewlist = nullptr; ListNode *pCur = pHead; ListNode *pPre = nullptr; while(pCur!=nullptr) { ListNode *pNext = pCur->next; if(pNext == nullptr) pNewlist = pCur; pCur->next = pPre; pPre = pCur; pCur = pNext; } return pNewlist; }};
6.合并两个排序的链表
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public: ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { if(pHead1==nullptr) return pHead1; if(pHead2==nullptr) return pHead2; ListNode *ptr1 = pHead1; ListNode *ptr2 = pHead2; ListNode *newlist = new ListNode(0); ListNode *cur = newlist; while(ptr1&&ptr2) { if(ptr1->val <= ptr2->val) { cur->next = ptr1; ptr1 = ptr1->next; cur = cur->next; } else { cur->next = ptr2; ptr2 = ptr2->next; cur = cur->next; } cur->next = nullptr; } if(ptr1) cur->next = ptr1; if(ptr2) cur->next = ptr2; return newlist->next; }};
7.两个链表的第一个公共节点
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public: unsigned int GetLength(ListNode* Node) { unsigned int length=0; ListNode* pNode=Node; while(pNode!=NULL) { ++length; pNode=pNode->next; } return length; } ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { unsigned int length1=GetLength(pHead1); unsigned int length2=GetLength(pHead2); int dislength=length1-length2; ListNode* pListNodeLong=pHead1; ListNode* pListNodeShort=pHead2; pListNodeLong=(length2>=length1)?pHead2:pHead1; pListNodeShort=(length2<length1)?pHead2:pHead1; for(int i=0;i<dislength;++i) pHead2=pHead2->next; while(pListNodeLong!=NULL)&&(pLietNodeShort!=NULL)&&(pListNodeLong!=pListNodeShort) { pListNodeLong=pListNodeLong->next; pListNodeShort=pListNodeShort->next; } ListNode* pFirst=pListNodeLong; return pFirst; }};
8.二叉搜索树与双向链表
9.复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
11.两个栈实现一个队列
template <typename T>class CQueue{public: CQueue(void); ~CQueue(void); void appendTail(const T& node); T deleteHead();private: stack<T> stack1; stack<T> stack2;};template<class T>void CQueue<T>::appendTail(const T& node)//在队列尾部添加数据{ stack1.push(node);}template<class T>T CQueue<T>::deleteHead(){ T tmp = 0; if (stack2.empty()) //若栈2为空 { while (!stack1.empty()) { tmp = stack1.top(); stack2.push(tmp); stack1.pop(); } } tmp = stack2.top(); stack2.pop(); return tmp;}
12.包含min函数的栈
13.栈的压入和弹出序列
/*输入两个整数序列,第一个序列表示栈的压入顺序, 请判断第二个序列是否为该栈的弹出顺序。假设压入 栈的所有数字均不相等。例如序列1,2,3,4,5是某栈 的压入顺序,序列4,5,3,2,1是该压栈序列对应的 一个弹出序列,但4,3,5,1,2就不可能是该压栈序列 的弹出序列。算法描述:首先判断两个序列的元素数目是否相等, 不相等,则肯定不是; 相等,进入下一步: 遍历Pop,每遍历一个数,先将Push数组里的压入栈,以i为push数组游标, 直到栈顶值与当前Pop值相等, ,然后弹出栈顶值,如果 直到i大于push数组的大小还没碰到栈顶值与pop数组相等 的值,则返回false*/class Solution {public: bool IsPopOrder(vector<int> pushV,vector<int> popV) { if (pushV.size() != popV.size()) return false; stack<int> s; int i = 0; for (int popData : popV) { while (s.empty() || s.top() != popData) { if (i == pushV.size()) return false; s.push(pushV[i++]); } s.pop(); } return true; }};
14. 题目描述
一个链表中包含环,请找出该链表的环的入口结点。
/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {public: ListNode* EntryNodeOfLoop(ListNode* pHead) { ListNode *pSlow = pHead; ListNode *pFast = pHead; do { if(!pSlow||!pFast) return nullptr; pSlow = pSlow->next; pFast = pFast->next; if(pFast) pFast = pFast->next; else return nullptr; } while(pSlow!=pFast); pSlow = pHead; while(pSlow!=pFast) { pSlow = pSlow->next; pFast = pFast->next; } return pSlow; }};
2. 剑指offer 寻找链表中的倒数第k个节点,和编程之美中判断两个链表是否相交类似,都是从链表尾部开始的。
编程之美的两道题目
1.从无头单链表中删除节点
由于单链表没有头指针,,不能简单的删除,会使得链表被分割
void DeleteRandomNode(Node* pCurrent)
{
Assert(pCurrent!=NULL)
*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) :* val(x), next(NULL) {* }* };*///输入一个链表,从尾到头打印链表每个节点的值。class Solution {public: vector<int> printListFromTailToHead(ListNode* head) { stack<ListNode*> S; ListNode* cur=head; while(cur) { S.push(cur); cur=cur->next; } vector<int>ans; while(!S.empty()) { cur=S.top(); S.pop(); ans.pushback(cur->val); } return ans; }};
0 0
- 剑指offer--堆、栈,队列、链表题目总结
- 总结: 堆、栈、队列
- <剑指offer>之栈和队列所有题目
- <剑指offer>之栈和队列所有题目
- 牛客网 - 剑指Offer - 考点:栈和队列 题目:用两个栈实现队列
- 栈和队列题目总结
- 《剑指Offer--栈-队列》
- <剑指offer>之链表题目
- <剑指offer>之链表题目
- 剑指Offer题目1518:反转链表
- 剑指offer重要题目整理总结
- 剑指offer 题目总结(上)
- 剑指Offer题目总结(java版)
- 《剑指offer》之链表、栈和队列专题
- 【剑指Offer面试编程题】题目1512:用两个栈实现队列--九度OJ
- [九度OnlineJudge][剑指Offer]题目1512:用两个栈实现队列
- 剑指offer-面试题07-衍生题目:用两个队列实现栈
- 堆、队列、栈、链表对比
- maven集成eclipse总结
- JS中的宽高理解
- Ubuntu-14.04.4-Server图解安装
- IP Networks (位运算)
- 直接插入排序算法
- 剑指offer--堆、栈,队列、链表题目总结
- Battery Historian for windows环境搭建
- Unity中使用ShareSDK微信登录的问题
- 详解协方差与协方差矩阵
- 根据一个代表星期几的0到6之间的整数,在屏幕上输出它代表星期几
- 如何在Linux VPS中保护MySQL与MariaDB数据库安全
- LeetCode 20. Valid Parentheses 判断()[]{}是否完整
- python二叉树遍历、求深度、已知前序中序 求树 求后序
- Properties的使用