Merging K Sorted Linked Lists











up vote
0
down vote

favorite












Specifically, how can I improve the time complexity of my algorithm (currently it is O(listLength * numberOfLists))? It only beats 5% of accepted LeetCode solutions, which surprised me.



/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
private void advance(final ListNode listNodes, final int index) {
listNodes[index] = listNodes[index].next;
}

public ListNode mergeKLists(final ListNode listNodes) {
ListNode sortedListHead = null;
ListNode sortedListNode = null;

int associatedIndex;

do {
int minValue = Integer.MAX_VALUE;
associatedIndex = -1;

for (int listIndex = 0; listIndex < listNodes.length; listIndex++) {
final ListNode listNode = listNodes[listIndex];

if (listNode != null && listNode.val < minValue) {
minValue = listNode.val;
associatedIndex = listIndex;
}
}

// An associated index of -1 indicates no more values left in any of the given lists
if (associatedIndex != -1) {
if (sortedListNode == null) {
sortedListNode = new ListNode(minValue);
sortedListHead = sortedListNode;
}
else {
sortedListNode.next = new ListNode(minValue);
sortedListNode = sortedListNode.next;
}

advance(listNodes, associatedIndex);
}
}
while (associatedIndex != -1);

return sortedListHead;
}
}


Note that the Solution class in addition to ListNode is already provided, the only code that I wrote was inside mergeKLists.










share|improve this question






















  • You correctly determined the complexity of your approach. No surprise that it fares low. Strive for O(listLength * log(numberOfLists)).
    – vnp
    Nov 24 at 6:15















up vote
0
down vote

favorite












Specifically, how can I improve the time complexity of my algorithm (currently it is O(listLength * numberOfLists))? It only beats 5% of accepted LeetCode solutions, which surprised me.



/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
private void advance(final ListNode listNodes, final int index) {
listNodes[index] = listNodes[index].next;
}

public ListNode mergeKLists(final ListNode listNodes) {
ListNode sortedListHead = null;
ListNode sortedListNode = null;

int associatedIndex;

do {
int minValue = Integer.MAX_VALUE;
associatedIndex = -1;

for (int listIndex = 0; listIndex < listNodes.length; listIndex++) {
final ListNode listNode = listNodes[listIndex];

if (listNode != null && listNode.val < minValue) {
minValue = listNode.val;
associatedIndex = listIndex;
}
}

// An associated index of -1 indicates no more values left in any of the given lists
if (associatedIndex != -1) {
if (sortedListNode == null) {
sortedListNode = new ListNode(minValue);
sortedListHead = sortedListNode;
}
else {
sortedListNode.next = new ListNode(minValue);
sortedListNode = sortedListNode.next;
}

advance(listNodes, associatedIndex);
}
}
while (associatedIndex != -1);

return sortedListHead;
}
}


Note that the Solution class in addition to ListNode is already provided, the only code that I wrote was inside mergeKLists.










share|improve this question






















  • You correctly determined the complexity of your approach. No surprise that it fares low. Strive for O(listLength * log(numberOfLists)).
    – vnp
    Nov 24 at 6:15













up vote
0
down vote

favorite









up vote
0
down vote

favorite











Specifically, how can I improve the time complexity of my algorithm (currently it is O(listLength * numberOfLists))? It only beats 5% of accepted LeetCode solutions, which surprised me.



/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
private void advance(final ListNode listNodes, final int index) {
listNodes[index] = listNodes[index].next;
}

public ListNode mergeKLists(final ListNode listNodes) {
ListNode sortedListHead = null;
ListNode sortedListNode = null;

int associatedIndex;

do {
int minValue = Integer.MAX_VALUE;
associatedIndex = -1;

for (int listIndex = 0; listIndex < listNodes.length; listIndex++) {
final ListNode listNode = listNodes[listIndex];

if (listNode != null && listNode.val < minValue) {
minValue = listNode.val;
associatedIndex = listIndex;
}
}

// An associated index of -1 indicates no more values left in any of the given lists
if (associatedIndex != -1) {
if (sortedListNode == null) {
sortedListNode = new ListNode(minValue);
sortedListHead = sortedListNode;
}
else {
sortedListNode.next = new ListNode(minValue);
sortedListNode = sortedListNode.next;
}

advance(listNodes, associatedIndex);
}
}
while (associatedIndex != -1);

return sortedListHead;
}
}


Note that the Solution class in addition to ListNode is already provided, the only code that I wrote was inside mergeKLists.










share|improve this question













Specifically, how can I improve the time complexity of my algorithm (currently it is O(listLength * numberOfLists))? It only beats 5% of accepted LeetCode solutions, which surprised me.



/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
private void advance(final ListNode listNodes, final int index) {
listNodes[index] = listNodes[index].next;
}

public ListNode mergeKLists(final ListNode listNodes) {
ListNode sortedListHead = null;
ListNode sortedListNode = null;

int associatedIndex;

do {
int minValue = Integer.MAX_VALUE;
associatedIndex = -1;

for (int listIndex = 0; listIndex < listNodes.length; listIndex++) {
final ListNode listNode = listNodes[listIndex];

if (listNode != null && listNode.val < minValue) {
minValue = listNode.val;
associatedIndex = listIndex;
}
}

// An associated index of -1 indicates no more values left in any of the given lists
if (associatedIndex != -1) {
if (sortedListNode == null) {
sortedListNode = new ListNode(minValue);
sortedListHead = sortedListNode;
}
else {
sortedListNode.next = new ListNode(minValue);
sortedListNode = sortedListNode.next;
}

advance(listNodes, associatedIndex);
}
}
while (associatedIndex != -1);

return sortedListHead;
}
}


Note that the Solution class in addition to ListNode is already provided, the only code that I wrote was inside mergeKLists.







java algorithm linked-list






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 at 0:12









Mar Dev

26229




26229












  • You correctly determined the complexity of your approach. No surprise that it fares low. Strive for O(listLength * log(numberOfLists)).
    – vnp
    Nov 24 at 6:15


















  • You correctly determined the complexity of your approach. No surprise that it fares low. Strive for O(listLength * log(numberOfLists)).
    – vnp
    Nov 24 at 6:15
















You correctly determined the complexity of your approach. No surprise that it fares low. Strive for O(listLength * log(numberOfLists)).
– vnp
Nov 24 at 6:15




You correctly determined the complexity of your approach. No surprise that it fares low. Strive for O(listLength * log(numberOfLists)).
– vnp
Nov 24 at 6:15










1 Answer
1






active

oldest

votes

















up vote
0
down vote













The time complexity is O(listLength * numberOfLists^2) because the check of which node is the smallest? is looking at one element of each list every iteration (so each iteration's complexity is O(numberOfLists)), and there are listLength * numberOfLists iterations.



You can get to O(listLength * numberOfLists * log(numberOfLists)) by using a sorted list of the ListNode elements that you are checking in each iteration, instead of the unsorted array listNodes. Let's call this list sortedNodes. You can avoid checking each element of sortedNodes every iteration because you know the first one is the smallest, and once you take this first value into the merged list and advance the node - do a binary search to decide where to move the first element after it's value has changed. (or remove it if it got to a null)






share|improve this answer























    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208315%2fmerging-k-sorted-linked-lists%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    The time complexity is O(listLength * numberOfLists^2) because the check of which node is the smallest? is looking at one element of each list every iteration (so each iteration's complexity is O(numberOfLists)), and there are listLength * numberOfLists iterations.



    You can get to O(listLength * numberOfLists * log(numberOfLists)) by using a sorted list of the ListNode elements that you are checking in each iteration, instead of the unsorted array listNodes. Let's call this list sortedNodes. You can avoid checking each element of sortedNodes every iteration because you know the first one is the smallest, and once you take this first value into the merged list and advance the node - do a binary search to decide where to move the first element after it's value has changed. (or remove it if it got to a null)






    share|improve this answer



























      up vote
      0
      down vote













      The time complexity is O(listLength * numberOfLists^2) because the check of which node is the smallest? is looking at one element of each list every iteration (so each iteration's complexity is O(numberOfLists)), and there are listLength * numberOfLists iterations.



      You can get to O(listLength * numberOfLists * log(numberOfLists)) by using a sorted list of the ListNode elements that you are checking in each iteration, instead of the unsorted array listNodes. Let's call this list sortedNodes. You can avoid checking each element of sortedNodes every iteration because you know the first one is the smallest, and once you take this first value into the merged list and advance the node - do a binary search to decide where to move the first element after it's value has changed. (or remove it if it got to a null)






      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        The time complexity is O(listLength * numberOfLists^2) because the check of which node is the smallest? is looking at one element of each list every iteration (so each iteration's complexity is O(numberOfLists)), and there are listLength * numberOfLists iterations.



        You can get to O(listLength * numberOfLists * log(numberOfLists)) by using a sorted list of the ListNode elements that you are checking in each iteration, instead of the unsorted array listNodes. Let's call this list sortedNodes. You can avoid checking each element of sortedNodes every iteration because you know the first one is the smallest, and once you take this first value into the merged list and advance the node - do a binary search to decide where to move the first element after it's value has changed. (or remove it if it got to a null)






        share|improve this answer














        The time complexity is O(listLength * numberOfLists^2) because the check of which node is the smallest? is looking at one element of each list every iteration (so each iteration's complexity is O(numberOfLists)), and there are listLength * numberOfLists iterations.



        You can get to O(listLength * numberOfLists * log(numberOfLists)) by using a sorted list of the ListNode elements that you are checking in each iteration, instead of the unsorted array listNodes. Let's call this list sortedNodes. You can avoid checking each element of sortedNodes every iteration because you know the first one is the smallest, and once you take this first value into the merged list and advance the node - do a binary search to decide where to move the first element after it's value has changed. (or remove it if it got to a null)







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 25 at 9:30

























        answered Nov 25 at 8:37









        potato

        20810




        20810






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208315%2fmerging-k-sorted-linked-lists%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Сан-Квентин

            Алькесар

            Josef Freinademetz