码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 143题:Reorder List的分析及两种解题思路

时间:2015-01-17 17:53:48      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

特别说明:参考了很多前辈的文章,整理如下,我只做了重新编码的工作,不能保证代码最优,主要用作交流学习。

题目:

技术分享

方法1:将链表的每个节点地址保存在指针数组中,利用数组随机访问调整链表。

 1 struct ListNode 
 2 {
 3     int val;
 4     ListNode *next;
 5     ListNode(int x) : val(x), next(NULL) {}
 6 };
 7 
 8 void reorderList(ListNode *head)
 9 {
10     if (head == nullptr)
11     {
12         return;
13     }
14 
15     vector<ListNode *> vecNode;
16     vector<ListNode *>::size_type left, right;
17     ListNode *p = head;
18     while (p)
19     {
20         vecNode.push_back(p);
21         p = p->next;
22     }
23 
24     left = 0;
25     right = vecNode.size() - 1;
26     while (left < right)
27     {
28         vecNode[left++]->next = vecNode[right];
29         vecNode[right--]->next = vecNode[left];
30     }
31     vecNode[left]->next = nullptr;
32 }

 

方法2:利用快慢两个指针将链表一分为二,针对第二个子链表求倒序,最后将两个子链表合并。

 1 class Solution {
 2 public:
 3     ListNode *GetMid(ListNode *head)                    //找到链表中点
 4     {
 5         if (head == nullptr || head->next == nullptr)
 6         {
 7             return head;
 8         }
 9 
10         ListNode *slow = head;
11         ListNode *fast = head->next;
12 
13         while (fast && fast->next)
14         {
15             slow = slow->next;
16             fast = fast->next->next;
17         }
18         return slow;
19     }
20 
21     ListNode *ReverseList(ListNode *head)                //链表逆置
22     {
23         if (head == nullptr || head->next == nullptr)
24         {
25             return head;
26         }
27 
28         ListNode *p = head;
29         ListNode *q = head->next;
30         ListNode *tmp = nullptr;
31 
32         while (q)
33         {
34             tmp = q->next;
35             q->next = p;
36             p = q;
37             q = tmp;
38         }
39         head->next = nullptr;
40 
41         return p;
42     }
43 
44     ListNode *UnionList(ListNode *head1, ListNode *head2)        //合并链表
45     {
46         if (head1 == nullptr)
47         {
48             return head2;
49         }
50         if (head2 == nullptr)
51         {
52             return head1;
53         }
54 
55         ListNode *p = head1;
56         ListNode *q = head2;
57         ListNode *tmpp = nullptr;
58         ListNode *tmpq = nullptr;
59 
60         while (p && q)
61         {
62             tmpp = p->next;
63             tmpq = q->next;
64 
65             p->next = q;
66             q->next = tmpp;
67 
68             p = tmpp;
69             q = tmpq;
70         }
71 
72         return head1;
73     }
74     
75     void reorderList(ListNode *head)                            //链表重排
76     {
77         if (head == nullptr || head->next == nullptr)
78         {
79             return;
80         }
81 
82         ListNode *head1 = nullptr;
83         ListNode *head2 = nullptr;
84         ListNode *mid = nullptr;
85 
86         mid = GetMid(head);
87         head2 = mid->next;
88         mid->next = nullptr;                    //分割成两个链表
89 
90         head2 = ReverseList(head2);
91         head1 = head;
92         head = UnionList(head1, head2);
93     }
94     
95 };

 

测试你的代码:

这里我提供一种比较好的方法,就是从文件中读入测试数据(多行),然后再分别对每行数据进行reorderList,这样可以方便同时测试多组数据。参考代码如下:

 1 void CreateList(ListNode **head, ListNode **tail, ListNode *n)                //创建链表
 2 {
 3     if (n != NULL)
 4     {
 5         if (*head == NULL)
 6         {
 7             *head = n;
 8             *tail = n;
 9             (*tail)->next = NULL;
10         }
11         else
12         {
13             (*tail)->next = n;
14             (*tail) = n;
15             (*tail)->next = NULL;
16         }
17     }
18 }
19 
20 int main(void)
21 {
22     ifstream in("data.txt");                            //打开data文件
23     string line;
24     int val;
25     ListNode *head = NULL;
26     ListNode *tail = NULL;
27     ListNode *n = NULL;
28 
29     while (getline(in, line))                            //每次读取一行数据至line中
30     {
31         istringstream clin(line);
32         while (clin >> val)                                //从每行数据中每次读取一个数据
33         {
34             n = new ListNode(val);
35             CreateList(&head, &tail, n);
36         }
37 
38         Solution List;
39         List.reorderList(head);
40 
41         while (head != NULL)
42         {
43             cout << head->val <<  ;
44             head = head->next;
45         }
46         cout << endl;
47 
48     }
49 
50     return 0;
51 }

效果如下:

技术分享

说明:通过阅读很多优秀的博客,采用方法2的最多,简单清晰。

LeetCode 143题:Reorder List的分析及两种解题思路

标签:

原文地址:http://www.cnblogs.com/mengwang024/p/4230478.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!