这是我在Leetcode上的“Merge Two Sorted Lists”算法问题的代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy, *pre;
dummy->next = l1;
pre = dummy;
while(l1 != NULL & l2 != NULL) {
if(l1->val < l2->val) {
pre = l1;
l1 = l1->next;
} else {
pre->next = l2;
l2->next = l1;
pre = l2;
l2 = l2->next;
}
}
if(l2 != NULL) {
pre->next = l2;
}
return dummy->next;
}
};
我收到了运行时错误。但是我的代码有什么问题?
答案 0 :(得分:2)
我认为正确的实现需要的代码比OP中的代码要多得多。这是一个正确的实现,你可以尝试。我假设输入列表l1
和l2
按降序排序(即从头到尾从最大到最小)。
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *pnt1 = l1;
ListNode *pnt2 = l2;
ListNode *head;
// assign the head pointer to larger head of the two input lists
if (l1->val > l2->val) {
head = l1;
}
else {
head = l2;
}
// walk through both lists sequentially,
// and splice together the sorted list
while (pnt1->next != NULL & pnt2->next != NULL) {
if(pnt2->val > pnt1->next->val && pnt1->val > pnt2->val) {
ListNode* next = pnt1->next;
pnt1->next = pnt2;
pnt1 = next;
}
else if(pnt2->val > pnt1->next->val && pnt1->val <= pnt2->val) {
ListNode* next = pnt2->next;
pnt2->next = pnt1;
pnt2 = next;
}
else if(pnt2->val <= pnt1->next->val && pnt1->val > pnt2->val) {
pnt1 = pnt1->next;
}
}
// handle edge case where end of one or two list(s) has been reached
if (pnt1->next == NULL && pnt2->next == NULL) {
if (pnt1->val > pnt2->val) {
pnt1->next = pnt2;
}
else {
pnt2->next = pnt1;
}
}
else if (pnt1->next == NULL) {
while (pnt2->next != NULL) {
if (pnt1->val > pnt2->next->val) {
ListNode* next = pnt2->next;
pnt2->next = pnt1;
pnt1->next = next;
break;
}
pnt2 = pnt2->next;
}
if (pnt2->next == NULL) {
pnt2->next = pnt1;
}
}
else if (pnt2->next == NULL) {
while (pnt1->next != NULL) {
if (pnt2->val > pnt1->next->val) {
ListNode* next = pnt1->next;
pnt1->next = pnt2;
pnt2->next = next;
break;
}
pnt1 = pnt1->next;
}
if (pnt1->next == NULL) {
pnt1->next = pnt2;
}
}
return head;
}
};
答案 1 :(得分:0)
我认为你有Segmentation Fault(Core Dump)
,因为你试图访问无效的内存:
dummy->next = l1;
在访问其成员之前,您应该为*dummy
和*pre
分配内存。
在循环中也使用&&
(逻辑运算符)而不是&
(按位运算符)。替换:
while(l1 != NULL & l2 != NULL) {
与
while(l1 != NULL && l2 != NULL) {
使用
new
运算符分配内存,请使用delete
释放内存并避免内存泄漏。另请注意,逻辑实现本身错误。有关更好的实施,请参阅here。
这是一个简单的递归实现:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
{
ListNode* result = NULL;
/* Base cases */
if (l1 == NULL)
return (l2);
else if (l2 == NULL)
return (l1);
if (l1->data <= l2->data)
{
result = l1;
result->next = mergeTwoLists(l1->next, l2);
}
else
{
result = l2;
result->next = mergeTwoLists(l1, l2->next);
}
return(result);
}
答案 2 :(得分:0)
您的代码中的主要问题是您正在使用:
dummy->next = l1;
当dummy
尚未初始化为指向有效对象时。
您还使用按位&
,其中逻辑&&
是合适的。
while(l1 != NULL & l2 != NULL) {
这是建议的实施方式。
PS 它没有经过测试,但看起来对我来说是正确的。
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* ret = NULL;
ListNode* pre = NULL;
// Make sure the start of the list to be returned points to the right
// ListNode.
if ( l1 != NULL && l2 != NULL )
{
if ( l1->val < l2->val )
{
ret = l1;
l1 = l1->next;
}
else
{
ret = l2;
l2 = l2->next;
}
}
else if ( l1 != NULL )
{
return l1;
}
else
{
return l2;
}
pre = ret;
while(l1 != NULL && l2 != NULL) {
// Figure out where pre->next must point to.
// Advance l1 and l2 appropriately.
if(l1->val < l2->val) {
pre->next = l1;
pre = l1;
l1 = l1->next;
} else {
pre->next = l2;
pre = l2;
l2 = l2->next;
}
}
// Make sure pre->next points to the remaining ListNodes.
// They could be in l1 or l2.
if ( l1 != NULL )
{
pre->next = l1;
}
if( l2 != NULL)
{
pre->next = l2;
}
return ret;
}
答案 3 :(得分:0)
除了已经指出的问题之外,原始代码还没有处理首先到达列表2的结尾的情况,在这种情况下,列表1的其余部分应该被附加到合并列表。使用指向指针(而不是前一个指针)的指针使代码更简单。下面是合并两个列表的示例代码,以及使用合并列表功能的自下而上合并排序。 sort使用指向列表的指针数组,其中array [i]为null或指向包含pow(2,i)元素的列表。
ListNode * MergeLists(ListNode *pl1, ListNode *pl2)
{
ListNode *plm = NULL; /* merged list head ptr */
ListNode **pplm = &plm; /* ptr to head or prev->next */
if(pl1 == NULL)
return pl2;
if(pl2 == NULL)
return pl1;
while(1){
if(pl2->val < pl1->val){ /* if src2 < src1 */
*pplm = pl2;
pl2 = *(pplm = &(pl2->next));
if(pl2 == NULL){
*pplm = pl1;
break;
}
} else { /* src1 <= src2 */
*pplm = pl1;
pl1 = *(pplm = &(pl1->next));
if(pl1 == NULL){
*pplm = pl2;
break;
}
}
}
return plm;
}
#define NUMLISTS 32 /* number of lists */
ListNode * SortList(ListNode *pList)
{
ListNode * aList[NUMLISTS]; /* array of lists */
ListNode * pNode;
ListNode * pNext;
int i;
if(pList == NULL) /* check for empty list */
return NULL;
for(i = 0; i < NUMLISTS; i++) /* zero array */
aList[i] = NULL;
pNode = pList; /* merge nodes into aList[] */
while(pNode != NULL){
pNext = pNode->next;
pNode->next = NULL;
for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
pNode = MergeLists(aList[i], pNode);
aList[i] = NULL;
}
if(i == NUMLISTS)
i--;
aList[i] = pNode;
pNode = pNext;
}
pNode = NULL; /* merge array into one list */
for(i = 0; i < NUMLISTS; i++)
pNode = MergeLists(aList[i], pNode);
return pNode;
}