重新排列链表

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 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值