簡體   English   中英

合並 K 個排序列表,不適用於邊緣情況,例如 null,只有 2 個列表 C++

[英]merge K sorted lists, not working for edge cases, like null, and only 2 lists C++

因此代碼適用於當列表數量大於 3 並且沒有 null 列表時,但是當有兩個或更少列表或空列表時顯示錯誤我正在比較每個列表的第一個元素並將 S 指向那個具有最小值,然后我將具有最小值的節點指向它的下一個節點,直到它是 null,當所有列表到達/變為 null 時,我打破循環並返回 head->next

for example
input = [[1,4,5],[1,3,4],[2,6]]
my output = [1,1,2,3,4,4,5,6]
expected = [1,1,2,3,4,4,5,6] this one is correct
but when a null list is there
example: input = [[1,4,5],[],[1,3,4],[2,6]]
it returns an error something like: AddressSanitizer: heap-buffer-overflow on address 0x...... error continues

=================================================================
==32==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000060 at pc 0x000000381d29 bp 0x7ffd73c87f70 sp 0x7ffd73c87f68
READ of size 8 at 0x603000000060 thread T0
    #3 0x7f28a234a82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x603000000060 is located 0 bytes to the right of 32-byte region [0x603000000040,0x603000000060)
allocated by thread T0 here:
    #6 0x7f28a234a82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
Shadow bytes around the buggy address:
  0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 07 fa fa 00 00 00 00[fa]fa fa fa
  0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==32==ABORTING

代碼:

    /**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* S = new ListNode();
        ListNode* head = S;
        int N = lists.size();
        int min = 0, count = 1;
        
        while ( count )
        {
            int k = 0;
            while( lists[k] == NULL && k < N )
                ++k;
            if( k == N  )
                break;
            min = k;
            count = 0;
            for(int j = 0; j < N; j++ )
            {
                if (lists[j] != NULL )
                {
                    if( lists[j]->val < lists[min]->val)
                        min = j;
                    
                    ++count;
                }
            }
            if( count == 0 )
                break;
            S->next = lists[min];
            S = S->next;
            if( lists[min] != NULL )
                lists[min] = lists[min]->next;
        }
        return head->next;
    }
};

如果您lists修剪為僅包含非空列表,則可以刪除對nullptr的大部分檢查。 你也是漏head

bool compareNode(ListNode * lhs, ListNode * rhs) {
    return lhs->val < rhs->val;
}

ListNode* mergeKLists(std::vector<ListNode*>& lists) {
    lists.erase(std::remove(lists.begin(), lists.end(), nullptr), lists.end());

    ListNode* head = nullptr;
    ListNode* curr = nullptr;
    
    while ( !lists.empty() )
    {
        auto it = std::min_element(lists.begin(), lists.end(), compareNode);
        if(head) {
            curr->next = *it;
        } else {
            curr = head = *it;
        }

        if (ListNode* next = (*it)->next) {
            *it = next;
        } else {
            lists.erase(it);
        }
    }

    return head;
}

所以問題是這種情況:

while( lists[k] == NULL && k < N )
            ++k;

當K = N - 1時,滿足條件並且k遞增並變為N,然后它嘗試訪問超出范圍的lists[N],因此出現錯誤。 將其固定為:

while( k < N && lists[k] == NULL )
            ++k;

現在它正在工作,感謝您的回答:)

如果我理解這個要求,當所有成員都按升序排列時,您希望將所有列表合並到一個輸出列表中。

#include <list>
#include <vector>
#include <map>

// 'Merge' function:

std::list<int> merge(std::vector<std::list<int>>& rlists)
{
    std::map<int, int> map;
    for (auto list : rlists)
        for (auto i : list)
            map[i]++;

    std::list<int> onelist;
    for (auto item : map)
        for (int i = item.second; i > 0; i--)
            onelist.push_back(item.first);

    return onelist;
}

//////////////// Use Case: ////////////////

int main()
{
    std::vector<std::list<int>> lists;

    lists.push_back(std::list<int>{ 1, 4, 5 });
    lists.push_back(std::list<int>{}); // Empty
    lists.push_back(std::list<int>{ 1, 3, 4 });
    lists.push_back(std::list<int>{ 2, 6 });

    std::list<int> onelist(merge(lists));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM