Leetcode reorder List
来源:互联网 发布:质量管理中的计量数据 编辑:程序博客网 时间:2024/05/06 16:36
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-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}
.
题目如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */
不同于一般的链表翻转,这里要求是链表要交叉着进行倒叙。
我的思路是:先寻找链表的中间节点,然后在此处对后半段的链表进行翻转,这里就得到前后两段顺序正常的链表,然后进行合并。程序用到了3个最
基本的链表操作,寻找中间节点findMiddle(), 链表翻转reverseList(),以及最终的合并reorderList()。
(1)寻找中间节点findMiddle()
给定一个链表*head, 利用一个first和second指针,前者每次前进一步,后者每次前进2步,当遍历完链表之后,first指针就是需要找的中间节点。但在leetcode上提交时几次出现了Runtime error 的问题。因为大多数寻找链表中间节点的操作只需要返回中间节点就够了,而在此处,除了找到中间节点first,还需要在此处将前后断开。在找到中间点first之后,要断开链表需要知道first的前驱,由于是单链表,无法直接得到前驱,所以我用了一个pre来保存。调用该函数后,first和second分别指向链表前一半和后一半的表头,代码如下:
struct Node* findMiddle(struct Node* head){ struct Node* first, *second ,*pre; first = second = head; if(NULL== head | NULL == head ->next) return head; else { while(second != NULL && second -> next != NULL ){ pre = first; first = first -> next; second = second -> next->next;} second = first; pre -> next = NULL; first = head;return second; }}
(2)翻转链表操作 reverse().给定一个链表*head,对其翻转操作。这里我用的是原址翻转,也就是不增加额外空间,在原地对链表进行操作,需要的是改变原链表的指针指向,用到3个变量pre, cur, nex,代码如下:
//reverse the totall Linklist 'head' without extra spacestruct Node* reverse(struct Node* head){ struct Node* pre = NULL;struct Node* cur= head;struct Node* nex= NULL;while(cur != NULL){ nex = cur -> next; cur -> next = pre; pre = cur; cur = nex;}head -> next = NULL;head = pre;return pre;}
(3)在归并之前,首先调用寻找终点函数, mid = findMiddle(*head), 得到前后两段链表,然后对后半段链表调用上个函数mid = reverse(mid)得到后半段已经逆序后的mid链表。至此,已经有了两段链表head和mid,现在需要对他们进行挨个插入排序,即在head的第1,2,3,4,...个节点之后分别插入mid的第1,2,3,...个节点。
这里有个细节需要注意,就是对于两段链表节点个数不一样的问题的边界处理。由于mid包含了原链表的中点,所以如果总节点个数为奇数个,那么必然是mid链表比head链表多出1个。每次进行处理的时候,需要先用head_nex和mid_nex来保存当前两段链表的后驱节点,然后插入过程需要进行判断,如果head_nex为空,则插入mid_nex,否则插入head_nex(这段逻辑大家好好体会下),代码如下:
void reorderList(ListNode *head) { if(head==NULL) return; else { struct ListNode* mid = findMiddle(head); mid = reverse(mid); // return the List reversed from the middle struct ListNode* head_nex, *mid_nex; head_nex = mid_nex = NULL; struct ListNode* newlist = head; if(head == mid) ; else while(head !=NULL && mid != NULL) { head_nex = head -> next; mid_nex = mid-> next; //insert the second element into the first Linklist mid -> next = (head -> next == NULL)?mid->next:head->next; head -> next = mid; head = head_nex; mid = mid_nex; } } // }
- [leetcode][list] Reorder List
- [leetcode][list] Reorder List
- Leetcode: Reorder List
- [LeetCode] Reorder List
- LeetCode题解:Reorder List
- Leetcode: Reorder List
- LeetCode:Reorder List
- leetcode之Reorder List
- Leetcode: Reorder List
- [LeetCode]Reorder List
- [LeetCode] Reorder List
- leetcode Reorder List
- LeetCode | Reorder List
- LeetCode Reorder List
- LeetCode 之 Reorder List
- Leetcode: Reorder List
- LeetCode OJ:Reorder List
- Reorder List (LeetCode)
- (总结归纳)常用电子元件,封装,库
- HDFS初探之旅
- [GEM5学习]1、GEM5仿真器启动过程
- VS2012+OpenCV+Python2.7配置
- 程序员必须进行的10项投资
- Leetcode reorder List
- 创建COM组件全过程
- Doom3 平方根求解算法的个人领悟 欢迎来讨论
- php Is_null
- Linux驱动开发常用调试工具-------之devmem
- sed, awk, nc
- C# 报表(reportview) 数据 绑定 (好像是水晶报表)
- WPF中图形表示语法详解(Path之Data属性语法)
- HttpURLConnection学习 (推荐)