[Frequency] by a singly linked list into small value left, center equal to the left of the large form

Title Description

Given a single head of the list head node, the node type of the value is an integer, to give a predetermined integer pivot. Implement a function to adjust the list, the list is the left node is less than the value of the pivot, the right side is greater than the pivot node.

E.g:

9-->0-->4-->5-->1  pivot = 3

Output:

1-->0-->4-->9-->5 也可以是
0-->1-->9-->5-->4

Thinking

Solution of this problem is the use of [ fast row / Finnish flag ] to solve the problem, except that this is the list, the list must first be converted into an array.

   public static class Node {
        int val;
        Node next;

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

    public static Node ListPartition1(Node head, int pivot) {
        if (head == null) {
            return null;
        }

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

    // 芬兰国旗问题
    private static void arrPartition(Node[] nodeArr, int pivot) {
        int small = -1;
        int big = nodeArr.length;
        int index = 0;
        while (index != big) {
            if (nodeArr[index].val < pivot) {
                swap(nodeArr, ++small, index++);
            } else if (nodeArr[index].val == pivot) {
                index++;
            } else {
                swap(nodeArr, --big, index);
            }
        }
    }

    private static void swap(Node[] nodeArr, int i, int index) {
        Node temp = nodeArr[i];
        nodeArr[i] = nodeArr[index];
        nodeArr[index] = temp;
    }

Advanced

New requirements

  1. Left, right three parts have to be sorted
  2. Time complexity is O (N), the spatial complexity is O (1)

Obviously the above-described solutions are not stable, spatial complexity is O (N)

Thinking:
left, right three parts ordering requirements, the value can be divided into three parts . Small portions, equal parts is greater than the portion.

Traverse the list from scratch in place for each list and pivot comparison, small on the small part of the large on the big part. So how do you store?

Each part requires maintaining two nodes, the head node and tail node.

  • Insertion node is empty, the head node is the end node of the inserted
  • The first node is not empty when, next insertion point to the end node of the node, and then moves to end node to the last node.

So three sort of part is stable. To merge the three parts of the last step, the last on the list to get sorted.
Code is implemented as follows:

public static Node listPartition2(Node head, int pivot) {
        Node sH = null;
        Node sT = null;
        Node eH = null;
        Node eT = null;
        Node bH = null;
        Node bT = null;
        Node next = null;

        while (head != null) {
            next = head.next;
            head.next = null;
            if (head.val < pivot) {
                if (sH == null) {
                    sH = head;
                    sT = head;
                } else {
                    sT.next = head;
                    sT = head;
                }
            } else if (head.val == 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;
        }

        if (sT != null) {
            sT.next = eH;
            eT = eT == null ? sT : eT;
        }
        if (eT != null) {
            eT.next = bH;
        }
        return sH != null ? sH : eH != null ? eH : bH;

    }

Published 89 original articles · won praise 13 · views 20000 +

Guess you like

Origin blog.csdn.net/Dawn510/article/details/105245730