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

Partition List

时间:2015-02-04 23:12:58      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

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

这个逻辑应该来讲还是比较清晰的,但是在整个区域后移一位的时候,由于循环内需要两个临时变量,和单纯的变量交换还是有很大不同,在这个子问题上,我考虑了很久,基本功弱的缺点毕现。

Partition List

标签:

原文地址:http://www.cnblogs.com/NickyYe/p/4273398.html

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