美文网首页算法
单向链表划分区域

单向链表划分区域

作者: 一凡呀 | 来源:发表于2017-12-07 17:11 被阅读0次

    题目:

    image.png

    思路1:

    把单向链表转化为结点数组,利用数组的partition过程(快排中),划分成要求的大于区小于区等于区

    注意:在数组中,以上for循环没有规定最后一个节点指针指向哪,默认不是指向null,是个野指针吧,另外,这里的i在上一步的for循环已经变成7了

    代码1:

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

    思路2:

    创建三个单链表,代表小于链表,大于链表,等于链表,通过比较整出链表,然后将三个链表合并起来

    注意,代码中有一步是,next = head.next, head.next=null,这一步是必须的,因为你在给每个区域的尾部赋值的时候,使用比如sT=head,如果head.next!=null的话,sT后面就拼接整个原来的单链表。此外在拼接的时候注意条件,具体看注释。

    代码2:

        public static Node listPartition2(Node head, int pivot) {
            Node sH = null; // small head
            Node sT = null; // small tail
            Node eH = null; // equal head
            Node eT = null; // equal tail
            Node bH = null; // big head
            Node bT = null; // big tail
            Node next = null; // save next node
            // every node distributed to three lists
            while (head != null) {
                next = head.next;
                head.next = null;
                if (head.value < pivot) {
                    if (sH == null) {
                        sH = head;
                        sT = head;
                    } else {
                        sT.next = head;
                        sT = head;
                    }
                } else if (head.value == pivot) {
                    if (eH == null) {
                        eH = head;
                        eT = head;
                    } else {
                        eT.next = head;
                        eT = head;
                    }
                } else {
                    if (bH == null) {
                        bH = head;
                        bT = head;
                    } else {
                        bT.next = head;
                        bT = head;
                    }
                }
                head = next;
            }
            // small and equal reconnect
            if (sT != null) {
                sT.next = eH;
    //如果等于区是空,说明上一行的sT.next = =null了,然后eT==null就把sT给eT,eT就相当于原来的sT了
                eT = eT == null ? sT : eT;
            }
            // all reconnect
            if (eT != null) {
                eT.next = bH;
            }
            return sH != null ? sH : eH != null ? eH : bH;
        }
    

    相关文章

      网友评论

        本文标题:单向链表划分区域

        本文链接:https://www.haomeiwen.com/subject/bufjixtx.html