以k

时间:2018-03-22 19:57:23

标签: java linked-list mergesort

遇到了编程问题,需要在k组中对给定的LinkedList进行排序。

例如:如果给定的链接列表为4->8->3->1->9->2且k = 3,则输出为3->4->8->1->2->9

我能够编写代码来对链表进行排序,但无法在组中进行。我用merge sort来做这件事。这是代码:

LinkedListNode sortedMerge(LinkedListNode a, LinkedListNode b) 
    {
        LinkedListNode result = null;

        if (a == null)
            return b;
        if (b == null)
            return a;


        if (a.val <= b.val) 
        {
            result = a;
            result.next = sortedMerge(a.next, b);
        } 
        else
        {
            result = b;
            result.next = sortedMerge(a, b.next);
        }
        return result;

    }

    LinkedListNode mergeSort(LinkedListNode h) 
    {

        if (h == null || h.next == null)
        {
            return h;
        }


        LinkedListNode middle = getMiddle(h);
        LinkedListNode nextofmiddle = middle.next;


        middle.next = null;


        LinkedListNode left = mergeSort(h);


        LinkedListNode right = mergeSort(nextofmiddle);

        // Merge the left and right lists
        LinkedListNode sortedlist = sortedMerge(left, right);
        return sortedlist;
    }


    LinkedListNode getMiddle(LinkedListNode h){

        //Base case
        if (h == null)
            return h;
        LinkedListNode fastptr = h.next;
        LinkedListNode slowptr = h;


        while (fastptr != null)
        {
            fastptr = fastptr.next;
            if(fastptr!=null)
            {
                slowptr = slowptr.next;
                fastptr=fastptr.next;
            }
        }
        return slowptr;
    }

以k组分组的方法定义是:

static LinkedListNode sort(int k, LinkedListNode list) {
    // Write your code here.
}

节点结构:

LinkedListNode {
    int val;
    LinkedListNode next;
};

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:1)

可能更有效率,但这使得策略更加清晰。您只需从列表中拆分第一个组,分别对组进行排序,然后重新加入它们。

static LinkedListNode sort(int k, LinkedListNode list) {
    LinkedListNode end = list;
    for (int i = 0; i < k - 1 && end.next != null; i++) {
        end = end.next; // get end of first group
    }
    if (end.next == null) {
        return mergeSort(list); // if last group, sort and return
    }

    LinkedListNode rest = sort(k, end.next); // sort rest of list
    end.next = null; // split first group from list
    list = mergeSort(list); // sort first group

    end = list;
    while (end.next != null) {
        end = end.next; // get end of sorted first group
    }
    end.next = rest; // rejoin sorted rest of list to sorted first group

    return list;
}

至于在群组中对内置List进行排序的相关问题,可以通过Collections.sortList.subList轻松处理:

static <T extends Comparable<? super T>> void sort(int k, List<T> list) {
    sort(k, list, null);
}

static <T> void sort(int k, List<T> list, Comparator<? super T> comp) {
    int size = list.size();
    for (int i = 0; i < size; i += k) {
        Collections.sort(list.subList(i, Math.min(i + k, size)), comp);
    }
}

答案 1 :(得分:0)

为什么要使用LinkedListNode呢?我编写了一个更简单的代码,将您的输入列表拆分为子列表,这些子列表是自己排序的。

import com.google.common.collect.Ordering;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class LinkedListSortByGroups {

    @Test
    public void doSort() {
        List<Integer> list = new LinkedList<>();
        list.addAll(Arrays.asList(4, 8, 3, 1, 9, 2));

        int groupSize = 3;
        Ordering<Comparable> ordering = Ordering.natural();

        List<Integer> sortedList = sortByGroup(list, groupSize, ordering);

        List<Integer> requirement = new LinkedList<>();
        requirement.addAll(Arrays.asList(3, 4, 8, 1, 2, 9));

        assertThat(sortedList.size(), is(requirement.size()));

        for (int i = 0; i < requirement.size(); i++) {
            assertThat(sortedList.get(i), org.hamcrest.Matchers.is(requirement.get(i)));
        }
    }

    private List<Integer> sortByGroup(List<Integer> listToSort, int groupSize, Ordering<Comparable> ordering) {
        List<Integer> sortedList = new LinkedList<>();

        for (int i = 0; i < listToSort.size(); i = i + groupSize) {
            // create sublist
            List<Integer> subList = new ArrayList<>(groupSize);
            // add first element - this is checked by for
            subList.add(listToSort.get(i));
            for (int offset = 1; offset < groupSize; offset++) {
                // fetch 'k' (group size) elements from original list
                if (i + offset < listToSort.size()) {
                    subList.add(listToSort.get(i + offset));
                }
            }
            // sort sublist
            subList.sort(ordering);
            sortedList.addAll(subList);
        }

        return sortedList;
    }
}

答案 2 :(得分:0)

这是我使用子列表进行就地排序的功能。

适用于List的任何Comparable

public static <T extends Comparable<? super T>> void sortInGroupsOf(final int k, List<T> list) {
    final int size = list.size();
    int fromI = 0;
    int toI = Math.min(fromI + k, size);
    while (fromI != size) {
        Collections.sort(list.subList(fromI, toI));
        fromI = toI;
        toI = Math.min(fromI + k, size);
    }
}


public static void main(String[] args) {
    @SuppressWarnings("boxing")
    LinkedList<Integer> list =
            new LinkedList<>(Arrays.asList(7, 3, 76, 8, 3, 4, 7, 87, 83, 2, 3, 7, 2, 2, 35));

    sortInGroupsOf(3, list);

    for (Integer i : list) {
        System.out.println(i);
    }
}

答案 3 :(得分:0)

包LinkedList;

public class SortInGroups {     / *      * @作者:Sahil      *日期:2018年4月21日      *      *给定链接列表和k,以k为一组对链接列表进行排序      *      *例子      *      *清单:      * 2-> 4-> 1-> 5-> 3-> 9-> 1-> 0-> 3      * k:3      *      *输出:对每个k组进行排序      * 1-> 2-> 4 ----&gt; 3→5→9 ----&GT; 0→1→3      *      *      *在Microsoft HackerRank问题中提问      * /

public Node sortGroupList(Node head, int k) {
    Node dummyHead = new Node(0);
    dummyHead.next = head;

    MergeSortLinkedList sorted = new MergeSortLinkedList();

    Node begin = dummyHead.next;

    Node temp;

    int i = 0;
    int firstTime = 0;
    Node prevEnd=null;

    while (head != null) {
        i++;

        if (i % k == 0) {
            firstTime++;
            temp = head.next;
            head.next = null;
            begin = sorted.sortList(begin);

            if(firstTime==1)
                dummyHead.next=begin;
            else{
                prevEnd.next=begin;
            }

            Node end = endNode(begin);
            end.next = temp;
            begin = temp;
            head = temp;
            prevEnd=end;
        } else {
            head = head.next;
        }
    }
    return dummyHead.next;
}

public Node endNode(Node head) {
    Node dummy = head;
    while (dummy.next != null) {
        dummy = dummy.next;
    }
    return dummy;
}

public static void main(String args[]) {
    SortInGroups sortLists = new SortInGroups();
    Node head = null;
    LinkList linkList = new LinkList();
    head = LinkList.addNode(2, head);
    head = LinkList.addNode(4, head);
    head = LinkList.addNode(1, head);
    head = LinkList.addNode(5, head);
    head = LinkList.addNode(3, head);
    head = LinkList.addNode(9, head);
    head = LinkList.addNode(1, head);
    head = LinkList.addNode(0, head);
    head = LinkList.addNode(3, head);
    head = sortLists.sortGroupList(head, 3);
    System.out.print("\n");
    linkList.printList(head);
}

}

包LinkedList;

公共类MergeSortLinkedList {     / *      * @作者:Sahil      *日期:2018年4月21日      *      *合并排序链表      *      * /

public Node sortList(Node head) {
    if (head == null || head.next == null)
        return head;

    // step 1. cut the list to two halves
    Node prev = null, slow = head, fast = head;

    while (fast != null && fast.next != null) {
        prev = slow;
        slow = slow.next;
        fast = fast.next.next;
    }

    prev.next = null;

    // step 2. sort each half
    Node l1 = sortList(head);
    Node l2 = sortList(slow);

    // step 3. merge l1 and l2
    return merge(l1, l2);
}

Node merge(Node l1, Node l2) {
    Node l = new Node(0);
    Node newList = l;

    while (l1 != null && l2 != null) {
        if (l1.data < l2.data) {
            newList.next = l1;
            l1 = l1.next;
        } else {
            newList.next = l2;
            l2 = l2.next;
        }
        newList = newList.next;
    }

    if (l1 != null)
        newList.next = l1;

    if (l2 != null)
        newList.next = l2;

    return l.next;
}


public static void main(String args[]) {

    MergeSortLinkedList sortList = new MergeSortLinkedList();
    Node head = null;
    LinkList linkList = new LinkList();
    head = LinkList.addNode(8, head);
    head = LinkList.addNode(3, head);
    head = LinkList.addNode(2, head);
    head = LinkList.addNode(5, head);
    head = LinkList.addNode(4, head);
    head = LinkList.addNode(7, head);
    head = LinkList.addNode(6, head);
    head = LinkList.addNode(1, head);
    head = sortList.sortList(head);
    LinkList.printList(head);
}

}