LeetCode.面试题02.04. 分割链表

题目地址:https://leetcode-cn.com/problems/partition-list-lcci/

 

题目描述:将一个链表以x值为“基准”,将链表分割成小于x的节点在x节点的左边,等于x,大于x的节点在右边。

 

解法一:遍历将链表中的每一个节点放入链表类型的数组中,对节点进行partition操作。

时间复杂度:O(N)

额外空间复杂度:O(N)

public static class Node {
        public int value;
        public Node next;

        public Node(int data) {
            this.value = data;
        }
    }

    public static Node listPartition1(Node head, int pivot) {
        if (head == null) {
            return head;
        }
        Node cur = head;
        int i = 0;
        
        //遍历链表,记录节点个数
        while (cur != null) {
            i++;
            cur = cur.next;
        }
        Node[] nodeArr = new Node[i];
        i = 0;
        cur = head;
        
        //将节点添加到数组
        for (i = 0; i != nodeArr.length; i++) {
            nodeArr[i] = cur;
            cur = cur.next;
        }
        //对数组做partition操作
        arrPartition(nodeArr, pivot);
        
        //将节点连起来
        for (i = 1; i != nodeArr.length; i++) {
            nodeArr[i - 1].next = nodeArr[i];
        }
        
        nodeArr[i - 1].next = null;
        
        return nodeArr[0];
    }

    public static void arrPartition(Node[] nodeArr, int pivot) {
        int small = -1;
        int big = nodeArr.length;
        int index = 0;
        while (index != big) {
            if (nodeArr[index].value < pivot) {
                swap(nodeArr, ++small, index++);
            } else if (nodeArr[index].value == pivot) {
                index++;
            } else {
                swap(nodeArr, --big, index);
            }
        }
    }

    public static void swap(Node[] nodeArr, int a, int b) {
        Node tmp = nodeArr[a];
        nodeArr[a] = nodeArr[b];
        nodeArr[b] = tmp;
    }

解法二:断链比较

 

利用六个变量,分别记录三个区域,小于区,等于区,大于区。

 

将每一个节点和目标值进行比较,小于目标值就将节点断开,将小于区的尾连接到该节点。

 

最后判断三个区域是否存在的情况

 

小于区存在,等于区不存在时,直接将小于区的Tail指向大于区的Head

 

小于区不存在,等于区存在,直接将等于区的Tail指向大于区的Head

 

最后判断三个区域的头节点是否存在,依次判断小于、等于、大于。

public ListNode partition(ListNode head, int x) {
        if (head == null){
            return null;
        }
        ListNode smallHead = null;
        ListNode smallTail = null;
        ListNode equalHead = null;
        ListNode equalTail = null;
        ListNode bigHead = null;
        ListNode bigTail = null;
        ListNode temp =null;
        while (head != null){
            temp = head.next;
            //将节点断链,重新排
            head.next = null;
            if (head.val < x){
                //如果小于区头节点==null,说明此时小于还没有节点,将新节点加入
                if (smallHead == null){
                    smallHead = head;
                    smallTail = head;
                }else {
                    //否则,小于区已经存在节点,将新节点插入小于区尾部
                    smallTail.next = head;
                    smallTail = head;
                }
            }else if (head.val == x){
                if (equalHead == null){
                    equalHead = head;
                    equalTail = head;
                }else {
                    equalTail.next = head;
                    equalTail = head;
                }
            }else {
                if(bigHead == null){
                    bigHead = head;
                    bigTail = head;
                }else {
                    bigTail.next = head;
                    bigTail = head;
                }
            }
            head = temp;
        }

        //对小于区、等于区、大于区是否存在进行判断
        if (smallTail != null){ //小于区存在
            smallTail.next = equalHead;

            //此时要判断等于区是否存在,因为如果等于区不存在,就要让小于区的尾去连大于区的头
            if (equalTail == null){
                smallTail.next = bigHead;
            }
        }
        if(equalTail != null){
            equalTail.next = bigHead;
        }
        //
        return smallHead != null ? smallHead : (equalHead != null ? equalHead : bigHead);
    }

 

posted @ 2020-09-27 11:08  硬盘红了  阅读(99)  评论(0编辑  收藏  举报