剑指Offer题解(六)链表问题

9 篇文章 0 订阅
9 篇文章 0 订阅
    #include<vector>
    #include<stack>
    
    using namespace std;
    

    #pragma region 从尾到头打印链表  链表 栈 可以递归
    
    //输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
    
    #pragma endregion
    
    struct ListNode {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :
    		val(x), next(NULL) {
    	}
    };
    
    class Solution {
    public:
    	vector<int> printListFromTailToHead(ListNode* head) {
    		std::stack<ListNode*> lStack;
    		ListNode* pNode = head;
    		while (pNode != nullptr)
    		{
    			lStack.push(pNode);
    			pNode = pNode->next;
    		}
    		vector<int> ret;
    		while (!lStack.empty())
    		{
    			ListNode *node = lStack.top();
    			ret.push_back(node->val);
    			lStack.pop();
    		}
    		return ret;
    	}
    };
    
    
    #pragma region 删除链表中重复的结点 链表 图 hashmap
    //在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
    //例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
    #pragma endregion
    
    #include<map>
    class Solution {
    public:
    	ListNode* deleteDuplication(ListNode* pHead)
    	{
    		std::map<int, int> nodeMap;
    		std::map<int, int>::iterator it;
    		ListNode* pTem = pHead;
    		while (pTem != nullptr)
    		{
    			it = nodeMap.find(pTem->val);
    			if (it != nodeMap.end())
    				(it->second)++;
    			else
    			{
    				nodeMap.insert(std::pair<int, int>(pTem->val, 1));
    			}
    			pTem = pTem->next;
    		}
    		ListNode* pRetHead = nullptr;
    		ListNode* pRet = nullptr;
    		ListNode* pItr = pHead;
    		while (pItr != nullptr)
    		{
    			it = nodeMap.find(pItr->val);
    			if (it == nodeMap.end())
    				break;
    			else
    			{
    				if (it->second == 1 && pRet == nullptr)
    				{
    					pRet = pItr;
    					pRetHead = pItr;
    				}
    				else if (it->second == 1 && pRet != nullptr)
    				{
    					pRet->next = pItr;
    					pRet = pRet->next;
    				}
    				else if (it->second > 1 && pRet != nullptr)
    				{
    					pRet->next = nullptr;
    				}
    			}
    			pItr = pItr->next;
    		}
    		return pRetHead;
    	}
    };
    
    
    
    #pragma region 链表中环的入口结点 链表 环 快慢指针
    //给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
    #pragma endregion
    
    class Solution {
    public:
    	ListNode* EntryNodeOfLoop(ListNode* pHead)
    	{
    		if (pHead == nullptr)
    			return nullptr;
    		ListNode* pFast = pHead;
    		ListNode* pSlow = pHead;
    		while (pFast != nullptr)
    		{
    			pSlow = pSlow->next;
    			pFast = pFast->next;
    			if (pFast != nullptr)
    			{
    				pFast = pFast->next;
    			}
    			if (pSlow == pFast)
    				break;
    		}
    		if (pFast == nullptr)
    			return nullptr;
    		else {
    			ListNode* pNewSlow = pHead;
    			while (pNewSlow != pSlow)
    			{
    				pNewSlow = pNewSlow->next;
    				pSlow = pSlow->next;
    			}
    			return pNewSlow;
    		}
    	}
    };
    
    
    
    #pragma region 两个链表的第一个公共结点 链表 公共结点 快慢指针
    //输入两个链表,找出它们的第一个公共结点。
    #pragma endregion
    class Solution {
    public:
    	ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
    		unsigned int length1 = 0;
    		unsigned int length2 = 0;
    		ListNode* tem_pHead1_1 = pHead1;
    		ListNode* tem_pHead2_1 = pHead2;
    		while (tem_pHead1_1 != nullptr)
    		{
    			tem_pHead1_1 = tem_pHead1_1->next;
    			length1++;
    		}
    		while (tem_pHead2_1 != nullptr)
    		{
    			tem_pHead2_1 = tem_pHead2_1->next;
    			length2++;
    		}
    		ListNode* long_pHead = pHead1;
    		ListNode* short_pHead = pHead2;
    		int length_Diff = length1 - length2;
    		if (length_Diff < 0)
    		{
    			long_pHead = pHead2;
    			short_pHead = pHead1;
    			length_Diff = -length_Diff;
    		}
    		while (length_Diff > 0)
    		{
    			long_pHead = long_pHead->next;
    			length_Diff--;
    		}
    		while (long_pHead != short_pHead && short_pHead != nullptr && long_pHead != nullptr)
    		{
    			long_pHead = long_pHead->next;
    			short_pHead = short_pHead->next;
    		}
    		ListNode* retNode = long_pHead;
    		return retNode;
    	}
    };
    
    
    #pragma region 复杂链表的复制 链表 复制 copy
    //输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
    //(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
    #pragma endregion
    
    struct RandomListNode {
    	int label;
    	struct RandomListNode *next, *random;
    	RandomListNode(int x) :
    		label(x), next(NULL), random(NULL) {
    	}
    };
    
    class Solution {
    public:
    	RandomListNode* Clone(RandomListNode* pHead)
    	{
    		if (!pHead) return nullptr;
    		RandomListNode* pNode = pHead;
    		while (pNode)
    		{
    			RandomListNode* temNode = new RandomListNode(pNode->label);
    			temNode->next = pNode->next;
    			pNode->next = temNode;
    			pNode = temNode->next;
    		}
    		pNode = pHead;
    		while (pNode)
    		{
    			RandomListNode* temNode = pNode->next;
    			if (pNode->random)
    				temNode->random = pNode->random->next;
    			pNode = temNode->next;
    		}
    		RandomListNode* pRetHead = pHead->next;
    		RandomListNode* temNode;
    		pNode = pHead;
    		while (pNode->next)
    		{
    			temNode = pNode->next;
    			pNode->next = temNode->next;
    			pNode = temNode;
    		}
    		return pRetHead;
    	}
    };
    
    
    
    
    #pragma region 链表中倒数第k个结点 链表 kth
    //输入一个链表,输出该链表中倒数第k个结点。
    
    #pragma endregion
    
    class Solution {
    public:
    	ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
    		if (pListHead == nullptr || k <= 0)
    			return nullptr;
    		ListNode* pListOne = pListHead;
    		ListNode* pListTwo = pListHead;
    		for (int i = 0; i < k - 1; i++)
    		{
    			pListTwo = pListTwo->next;
    			if (pListTwo == nullptr)
    				return nullptr;
    		}
    		while (pListTwo->next != nullptr)
    		{
    			pListTwo = pListTwo->next;
    			pListOne = pListOne->next;
    		}
    		return pListOne;
    
    	}
    };
    
    
    
    #pragma region 合并两个排序的链表 链表 合并 单调 递增
    //输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
    #pragma endregion
    class Solution {
    public:
    	ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    	{
    		if (!pHead1)
    			return pHead2;
    		else if (!pHead2)
    			return pHead1;
    		ListNode* pRet;
    		ListNode* pRetHead;
    		if (pHead1->val <= pHead2->val)
    		{
    			pRetHead = pRet = pHead1;
    			pHead1 = pHead1->next;
    		}
    		else
    		{
    			pRetHead = pRet = pHead2;
    			pHead2 = pHead2->next;
    		}
    		while (pHead1 || pHead2)
    		{
    			if (!pHead1)
    			{
    				pRet->next = pHead2;
    				break;
    			}
    			else if (!pHead2)
    			{
    				pRet->next = pHead1;
    				break;
    			}
    			else if (pHead1->val <= pHead2->val)
    			{
    				pRet->next = pHead1;
    				pRet = pRet->next;
    				pHead1 = pHead1->next;
    			}
    			else
    			{
    				pRet->next = pHead2;
    				pRet = pRet->next;
    				pHead2 = pHead2->next;
    			}
    		}
    		return pRetHead;
    	}
    };
    
    
    
    #pragma region 反转链表 
    //输入一个链表,反转链表后,输出新链表的表头。
    
    #pragma endregion
    
    
    class Solution {
    public:
    	ListNode* ReverseList(ListNode* pHead) {
    		if (!pHead)
    			return nullptr;
    		ListNode* pBefore = new ListNode(pHead->val);
    		while (pHead->next)
    		{
    			ListNode* pLatter = new ListNode(pHead->next->val);
    			pLatter->next = pBefore;
    			pBefore = pLatter;
    			pHead = pHead->next;
    		}
    		return pBefore;
    	}
    };
    
    
    
    #pragma region 孩子们的游戏(圆圈中最后剩下的数) 循环链表 list 
    //每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。
    //HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。
    //然后,他随机指定一个数m,让编号为0的小朋友开始报数。
    //每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,
    //从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。
    //请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
    #pragma endregion
    
    #include<list>
    class Solution {
    public:
    	int LastRemaining_Solution(int n, int m)
    	{
    		if (n < 1 || m < 1)
    			return -1;
    		list<int> circle;
    		for (int i = 0; i < n; ++i)
    			circle.push_back(i);
    		list<int>::iterator itr = circle.begin();
    		while (circle.size() > 1)
    		{
    			for (int i = 1; i < m; ++i)
    			{
    				++itr;
    				if (itr == circle.end())
    					itr = circle.begin();
    			}
    			list<int>::iterator next = ++itr;
    			if (next == circle.end())
    				next = circle.begin();
    			circle.erase(--itr);
    			itr = next;
    		}
    		return *itr;
    	}
    };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值