闲话链表(三) leetcode之Partition List
2014-10-12 22:02
435 查看
描述
Given a linked list and a value x,partition it such that all nodes less than x come before nodes greater than orequal to x.
You should preserve the original relativeorder of the nodes in each of the two partitions.
For example, Given1->4->3->2->5->2 and x = 3, return1->2->2->4->3->5.
分析:就是考察单链表指针的操作,本人采用的策略是模仿快速排序中partition的一个实现版本。指针p从前往后扫描,对当前的节点判断其val是否满足小于x的条件,如满足,则这个节点就要摘取出来,插到它合适的位置。那哪里才是它合适的位置?我们用另一个指针q表示当前找到的最后一个满足val<x的节点,那么新的节点很明显就是插入到q之后,插入之后,q也往后移一步,指向新插入的节点。
几个陷阱:
1、 可能第一个节点val就会小于x,一般情况下的插入不一定能正确处理这种特殊情况。我采取的策略是跳过它。反正它插入了也还是在第一个位置,只需要把q指针往后移就行了。
2、 第二个陷阱太坑爹了,干看着它出错就是想不出好办法能解决它。见下图:
在一般情况下,即prev!=q,这时候插入完成后prev的next就是下一个要处理的节点,也就是val等于5的节点。
然而在第二种情况里,插入完成后其实链表是没有任何改变的,这时候prev的next还是原来的p,p没有向后移动,程序陷入了一个死循环。
最后实在想不出好办法,只好写个if,当prev==q的时候,再另外对prev做处理,即prev=p
后记:AC完之后看其他人写的代码,感觉他人的代码思路更直观、写起来也不容易出错。但我也就当练练手了,这种两个指针p、q的思想处理某些问题来还是很给力的。这里简要介绍下另一种做法。
新建两个单链表,L1、L2
每次拆下一个节点,若val<x,则插入链表L1;反之,插入L2。则当所有节点处理完毕后,L1中是所有val<x的节点,L2中是所有val>=x的节点,最后把L2加在L1后面,返回L1的head。
Given a linked list and a value x,partition it such that all nodes less than x come before nodes greater than orequal to x.
You should preserve the original relativeorder of the nodes in each of the two partitions.
For example, Given1->4->3->2->5->2 and x = 3, return1->2->2->4->3->5.
分析:就是考察单链表指针的操作,本人采用的策略是模仿快速排序中partition的一个实现版本。指针p从前往后扫描,对当前的节点判断其val是否满足小于x的条件,如满足,则这个节点就要摘取出来,插到它合适的位置。那哪里才是它合适的位置?我们用另一个指针q表示当前找到的最后一个满足val<x的节点,那么新的节点很明显就是插入到q之后,插入之后,q也往后移一步,指向新插入的节点。
几个陷阱:
1、 可能第一个节点val就会小于x,一般情况下的插入不一定能正确处理这种特殊情况。我采取的策略是跳过它。反正它插入了也还是在第一个位置,只需要把q指针往后移就行了。
2、 第二个陷阱太坑爹了,干看着它出错就是想不出好办法能解决它。见下图:
在一般情况下,即prev!=q,这时候插入完成后prev的next就是下一个要处理的节点,也就是val等于5的节点。
然而在第二种情况里,插入完成后其实链表是没有任何改变的,这时候prev的next还是原来的p,p没有向后移动,程序陷入了一个死循环。
最后实在想不出好办法,只好写个if,当prev==q的时候,再另外对prev做处理,即prev=p
<span style="font-size:18px;">class Solution { public: ListNode *partition(ListNode *head, int x) { if(head == NULL) return NULL; ListNode* fakehead = new ListNode(-1); fakehead -> next = head; ListNode *p = head; ListNode *prev = fakehead; ListNode *q = fakehead; //若第一个节点val<x,则更新q if(p -> val < x) q = p; prev = p; p = p -> next; //遍历第一个节点之后的节点 while(p) { if(p -> val < x) { prev -> next = p -> next; p -> next = q -> next; q -> next = p; //坑爹情况下prev的更新 if(prev == q) prev = p; q = p; p = prev -> next; } else { prev = p; p = p -> next; } } return fakehead -> next; } };</span>
后记:AC完之后看其他人写的代码,感觉他人的代码思路更直观、写起来也不容易出错。但我也就当练练手了,这种两个指针p、q的思想处理某些问题来还是很给力的。这里简要介绍下另一种做法。
新建两个单链表,L1、L2
每次拆下一个节点,若val<x,则插入链表L1;反之,插入L2。则当所有节点处理完毕后,L1中是所有val<x的节点,L2中是所有val>=x的节点,最后把L2加在L1后面,返回L1的head。
相关文章推荐
- 闲话链表(二) leetcode 之 Reverse Linked List II
- leetcode Partition List二分链表问题
- 闲话链表(四) leetcode之Remove Duplicates from Sorted List I、II
- leetcode:Partition List (链表处理)【面试算法题】
- leetcode_c++:链表:Partition List (086)
- LeetCode Partition List 按值分段链表 系统分析
- leetcode Partition List链表
- leetcode---partition-list---链表
- LeetCode刷题笔记(链表):partition-list
- leetcode:单链表之Partition List
- LeetCode Partition List(链表分段)
- Leetcode Partition List 分割链表
- LeetCode2.2.3 @ Partition List 链表划分 D3F3
- LeetCode(Partition List) 划分链表
- Reorder List 链表首尾交叉排列@LeetCode
- Leetcode Reverse Linked List II 反转特定区间的链表
- Reverse Linked List II 局部翻转链表@LeetCode
- leetcode JAVA Partition List 难度系数3 3.30
- Leetcode Sort List 链表归并排序
- Flatten Binary Tree to Linked List 二叉树变成链表@LeetCode,