现在的位置: 首页 > 综合 > 正文

重新排列链表

2018年02月01日 ⁄ 综合 ⁄ 共 1922字 ⁄ 字号 评论关闭
LeetCode : 

Reorder List

 

LeetCode上有下面这样一个题目,比较有意思,拿来实现,权当练习基本功了:

Reorder List

 Total Accepted: 8598 Total
Submissions: 44508
My Submissions

Given a singly linked list LL0L1→…→Ln-1Ln,

reorder it to: L0LnL1Ln-1L2Ln-2→…

You must do this in-place without altering the nodes' values.

For example,

Given {1,2,3,4}, reorder it to {1,4,2,3}.

题目要求我们算法是in-place的,因此我们不能够通过交换value的值来实现,只能对链表进行重新链接。
对于本题,我的思路是这样的:经过观察发现,reorder后的链表是原来链表前半部分后半部分的逆序交叉链接得到的。
因此:
1. 首先找到原来链表的中间节点mid,将原链表分成两部分;
2. 前面部分存入一个队列queue中;
3. 后半部分则存入一个栈stack中(这样取出来的时候自动逆序);
4. 然后再将队列这栈中的元素交替取出,并链接取来,从而得到reorder后的结果。
思想很简单,下面直接上已经AC过的代码,如果你还有更好的思路请告诉我,希望学习进步:
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;

 struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
 };

class Solution {
public:
	//找到链表的中间节点
	ListNode *findMiddle(ListNode *head) 
	{
		if (head == NULL) return NULL ;
		ListNode *p1 = head ;
		ListNode *p2 = head->next ;

		while(p2 != NULL && p2->next != NULL)
		{
			p1 = p1->next ;
			p2 = p2->next->next ;
		}
		return p1 ;
	}

    void reorderList(ListNode *head) {

        if (head == NULL) return ;
		if (head->next == NULL) return ;

		ListNode *tmpHead = head ;
		queue<ListNode*> q ; //使用队列存储前半部分
		stack<ListNode*> s ;  //使用栈保存后半部分

		ListNode *midPtr = findMiddle(head) ;
		midPtr = midPtr->next ;
		//前半部分存入队列
		while (tmpHead != midPtr)
		{
			q.push(tmpHead) ;
			tmpHead = tmpHead->next ;
		}
		//后半部分存入栈
		while (midPtr != NULL)
		{
			s.push(midPtr) ;
			midPtr = midPtr->next ;
		}

		//将两部分合并
		ListNode *ptr = q.front() ;
		q.pop() ;
		while (!q.empty())
		{
			ptr->next = s.top() ;
			s.pop() ;
			ptr = ptr->next ;

			ptr->next = q.front() ;
			q.pop() ;
			ptr = ptr->next ;
		}
		while (!s.empty()) //一定有s.size() >= q.size()
		{
			ptr->next = s.top() ;
			s.pop() ;
			ptr = ptr->next ;
		}

		ptr->next = NULL ;
    }
};

ifstream in("data.txt") ;
#define cin in

int main(int argc, char **argv)
{
	ListNode *head = NULL;
	ListNode *tail = head;
	int tmpN;
	while (cin >> tmpN)
	{
		ListNode *tmpNode = new ListNode(tmpN) ;
		if (head == NULL)
		{
			head = tmpNode ;
			tail = head ;
		}
		else
		{
			tail->next = tmpNode ;
			tail = tmpNode ;
		}
	}

	Solution s ;
	s.reorderList(head) ;

	ListNode *ptr = head ;
	while (ptr)
	{
		cout << ptr->val << " " ;
		ptr = ptr->next ;
	}
	cout << endl;

	return 0 ;
}

【上篇】
【下篇】

抱歉!评论已关闭.