标签:
https://oj.leetcode.com/problems/partition-list/
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2
and x = 3,
return 1->2->2->4->3->5
.
解题思路:
这个题目不算复杂, 但我在其中的一个子问题上卡了很长时间,只能说是代码太不熟悉。
从宏观上思考题目,遇到比x小的节点(1)可直接跳过不管。遇到>=x的节点,就把他们都[4,3]往后移动,移到下一个比x小(2)的节点,再把这个小于x的节点(2)放到之前大于x区域的第一个位置(4)。等等,这么说好像有点问题,其实是反过来了。为什么?
其实是,遇到>=x的节点不动,但是记录一个位置,就是这个连续都是>=x数字的区域的第一个位置。一旦遇到<x的节点,那么这个区域就清晰了,里面所有元素都>=x。于是,将这个区域整体后移一个,再将当前<x的这个节点放到这个区域的第一个。类似于将区域的最后一个元素放到首元素。这样,原来元素的顺序也不会打乱,是稳定的变化。
同时,把记录这个>=x区域的开始位置后移一个,因为他们都只后移了一位。
然后游标往后,继续遍历整个链表。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode partition(ListNode head, int x) { ListNode swapNode = head; ListNode traverseNode = head; ListNode returnNode = head; while(traverseNode != null){ if(traverseNode.val >= x){ //do nothing } //考虑例子1->4->3->2->5->2,traverse到2,swapNode在1 if(traverseNode.val < x){ //留着一个备份,因为下面swapNode要往后移动,一直到traverseNode ListNode tempNode = swapNode; //给traverseNode的值留一个备份,后面和swapNode后节点交换 int temp = traverseNode.val; //从[swapNode, traverseNode)每个节点往后移一个 //即变成1->4->4->3->5->2 int pre = swapNode.val; while(swapNode != traverseNode){ int tempValue = swapNode.next.val; swapNode.next.val = pre; pre = tempValue; swapNode = swapNode.next; } //将前面存的最后一个值,2,赋予第一个节点4 //即变成1->2->4->3->5->2 tempNode.val = temp; //swapNode从原先的位置往后移动一个 swapNode = tempNode.next; } // if(swapNode != null && swapNode.val < x){ // swapNode = swapNode.next; // } traverseNode = traverseNode.next; } return returnNode; } }
这个逻辑应该来讲还是比较清晰的,但是在整个区域后移一位的时候,由于循环内需要两个临时变量,和单纯的变量交换还是有很大不同,在这个子问题上,我考虑了很久,基本功弱的缺点毕现。
标签:
原文地址:http://www.cnblogs.com/NickyYe/p/4273398.html