[Leetcode] Partition List

Partition List 题解

题目来源:https://leetcode.com/problems/partition-list/description/


Description

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.

Example

Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.

Solution


class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if (head == NULL || head -> next == NULL)
            return head;
        ListNode *lowHead = NULL, *highHead = NULL;
        ListNode *lowTail = NULL, *highTail = NULL;

        // 找到最靠前的小于x的链表段头尾和大于x的链表段头尾
        if (head -> val < x)
            lowHead = lowTail = head;
        else
            highHead = highTail = head;
        if (lowHead) {
            while (lowTail -> next) {
                if (lowTail -> next -> val < x) {
                    lowTail = lowTail -> next;
                } else {
                    highHead = highTail = lowTail -> next;
                    break;
                }
            }
            if (!highHead)
                return head;
        } else {
            while (highTail -> next) {
                if (highTail -> next -> val >= x) {
                    highTail = highTail -> next;
                } else {
                    lowHead = lowTail = highTail -> next;
                    break;
                }
            }
            if (!lowHead)
                return head;
        }

        if (highHead == head) {
            // 将小于x的链表段放到大于x的链表段前面
            highTail -> next = lowTail -> next;
            lowTail -> next = highHead;
        }

        // 每次向后探测一个节点,如果大于x则不移动,如果小于x就加到小于x的链表段尾部,
        // 直到读取完整个链表
        while (highTail -> next) {
            if (highTail -> next -> val >= x) {
                highTail = highTail -> next;
            } else {
                lowTail -> next = highTail -> next;
                lowTail = lowTail -> next;
                highTail -> next = lowTail -> next;
                lowTail -> next = highHead;
            }
        }
        return lowHead;
    }
};


解题描述

这道题题意是给出一个链表和一个数x,要求将链表中所有大于或等于x的节点放到小于x的节点后面,前变换位置前后,高低两个链表段内节点的顺序和原链表相同。上面是我自己AC的解法,算法已经写在注释中。虽然这个解法可以在一趟之内完成,但是相对比较繁琐,下面给出的是评论区的高票解法:


class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if (head == NULL || head -> next == NULL)
            return head;
        ListNode *lowHead = new ListNode(0);
        ListNode *highHead = new ListNode(0);
        ListNode *lowTail = lowHead, *highTail = highHead;
        while (head) {
            if (head -> val < x) {
                lowTail -> next = head;
                lowTail = lowTail -> next;
            } else {
                highTail -> next = head;
                highTail = highTail -> next;
            }
            head = head -> next;
        }
        highTail -> next = NULL;
        lowTail -> next = highHead -> next;
        head = lowHead -> next;
        delete lowHead;
        delete highHead;
        return head;
    }
};


其采用的办法是对原来的链表构建2个新的链表lowhigh,然后从前向后扫描链表,每次根据节点元素大小分别放到两个新链表尾部,最后再将high接到low后面即可。

posted @ 2018-01-30 13:31  言何午  阅读(377)  评论(0编辑  收藏  举报