遇到了编程问题,需要在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;
};
有人可以帮忙吗?
答案 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.sort
和List.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);
}
}