Merge 这是合并两个排序列表的问题。我能理解问题出在哪里?

Merge 这是合并两个排序列表的问题。我能理解问题出在哪里?,merge,linked-list,mergesort,Merge,Linked List,Mergesort,程序接受两个已排序的链表,并通过合并这些链表返回一个链表。我也写了考虑边缘情况的逻辑,但是没有输出。我认为问题在于形成第三个链表。我无法形成第三个链表 class Solution { public: ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { ListNode *l3 = new ListNode(0); ListNode *head = l3; ListNode *temp

程序接受两个已排序的链表,并通过合并这些链表返回一个链表。我也写了考虑边缘情况的逻辑,但是没有输出。我认为问题在于形成第三个链表。我无法形成第三个链表

class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        ListNode *l3 = new ListNode(0);
        ListNode *head = l3;
        ListNode *temp = new ListNode();
        if (!l1 && !l2) {
            return l1;
        } else if (!l1) {
            return l2;
        } else if (!l2) {
            return l1;
        } else if (l1->val <= l2->val) {
            l3->val = l1->val;
            l1 = l1->next;
        } else {
            l3->val = l2->val;
            l2 = l2->next;
        }
        while (l1->next || l2->next) {
            print(head);
            print(l1);
            print(l2);
            if (l1->val <= l2->val) {
                temp->val = l1->val;
                l1 = l1->next;
            } else {
                temp->val = l2->val;
                l2 = l2->next;
           }
            print(temp);
            //l3 = l3->next;
            l3->next = temp;
            l3 = l3->next;
        }
        return head;
    }
};
类解决方案{
公众:
ListNode*MergeTwoList(ListNode*l1,ListNode*l2){
ListNode*l3=新ListNode(0);
ListNode*head=l3;
ListNode*temp=新ListNode();
如果(!l1&&!l2){
返回l1;
}else如果(!l1){
返回l2;
}else如果(!l2){
返回l1;
}否则如果(l1->val){
l3->val=l1->val;
l1=l1->next;
}否则{
l3->val=l2->val;
l2=l2->next;
}
同时(l1->next | l2->next){
打印头;
打印(l1);
打印(l2);
如果(l1->val){
温度->瓦尔=l1->瓦尔;
l1=l1->next;
}否则{
温度->值=l2->值;
l2=l2->next;
}
打印(临时);
//l3=l3->next;
l3->next=温度;
l3=l3->next;
}
回流头;
}
};

您的核心问题在于您没有为新列表中的每个项目分配新节点:

从l3开始,它是一个新的列表节点,表示合并列表的开始,并将
l3->val
设置为正确的开始值(最小值
l1->val
l2->val
)。稍后,您将对
temp
执行类似的操作,评估列表的“当前”节点(现在由l1和l2指向),并将
temp->val
设置为两个节点中的最小值问题在于,l1、l2、l3和temp都是指向列表节点的指针。您反复将l3->next设置为指向同一块内存(由temp指向),每次循环迭代都会覆盖基础值成员。我的建议是,将temp的任务视为“传递”它所指向的ListNode(变成
l3->next
),并更改为指向一个新的内存块以保存一个新的ListNode(用于下一次迭代),或者更好的方法是通过从l1或l2中提取min值,然后执行一个简单的
l3->next=new ListNode(min_val)
来完全消除temp。它可能有助于绘制一个l1、l2和l3都指向独立内存块的内存图,这样您就可以四处移动箭头并捕获更多的边缘情况

其他一些可能会让你绊倒的事情:

1) 想想你的循环条件——你已经(在循环之前和循环中)设置了
l1=l1->next
l2=l2->next
,并继续在循环条件中引用该new值的
next
成员,而没有检查该新值本身是否为空。当您到达一个列表的末尾,而不是另一个列表的末尾时,此陷阱(空取消引用)也会影响对val成员的检查

2) 您的起始
l3->val
为0,使用任意数字通常不是很好的做法。在检查l1和l2都不为空之后,这将是一个整合的好时机,类似于
ListNode*l3=newlistnode(min(l1->val,l2->val))

3) 您的第一个条件没有用处,因为(如果我假设两个列表都为空,则返回null是正确的),一个列表为null意味着返回另一个列表是正确的,这通过以下两个条件发生


我希望这有帮助

如果目标是合并列表,则不应分配新节点,而只需更改
next
成员以形成单个有序列表。分为两个阶段:

  • 只要两个列表中都有节点,就比较头部节点以确定从哪个列表中获取第一个元素,并将其链接到合并列表
  • 当其中一个列表用尽时,将另一个列表链接到合并列表的末尾
要链接合并列表末尾的元素,请保留指向最后一个节点的指针

以下是修改后的版本:

类解决方案{
公众:
ListNode*MergeTwoList(ListNode*l1,ListNode*l2){
ListNode*head=NULL;
ListNode*tail=NULL;
ListNode*n;
while(l1和l2){
如果(l1->val){
n=l1;
l1=l1->next;
}否则{
n=l2;
l2=l2->next;
}
如果(尾部){
tail=tail->next=n;
}否则{
尾=头=n;
}
}
如果(l1){
n=l1;
}否则{
n=l2;
}
如果(尾部){
tail->next=n;
}否则{
水头=n;
}
回流头;
}
};
掌握双指针后,可以改进此代码并删除head节点的测试:

类解决方案{
公众:
ListNode*MergeTwoList(ListNode*l1,ListNode*l2){
ListNode*head=NULL;
ListNode**nextp=&head;
while(l1和l2){
如果(l1->val){
*nextp=l1;
nextp=&l1->next;
l1=l1->next;
}否则{
*nextp=l2;
nextp=&l2->next;
l2=l2->next;
}
}
*nextp=l1?l1:l2;
回流头;
}
};

我会详细说明您所说的“没有输出”是什么意思。输出是什么?完全没有,空的,不正确的..这是超越时间的problem@mansithakur:单击分数下方的灰色复选标记,您可以接受其中一个答案。