如何解决在C ++中以不同的方式创建节点时会感到困惑吗?
我正在尝试解决leetcode中合并两个排序的链表的问题。
我解决了问题,但是有些事情我还不了解,当我尝试使用'new'关键字(将节点存储在堆内存中)创建节点及其指针时,它可以工作,但是当我将其更改为首先创建节点然后创建指向它的指针时,它会显示“范围后使用堆栈” 。
这是注释的代码-
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) {}
};
ListNode* mergeTwoLists(ListNode* l1,ListNode* l2) {
if(l1==NULL) return l2;
if(l2==NULL) return l1;
// ListNode *res = new ListNode() works but this doesn't
ListNode dummy(0);
ListNode *res = &dummy;
// just comparing the initial 2 values of both linked list-
if(l1->val<l2->val){
res->val=l1->val;
l1=l1->next;
}else{
res->val=l2->val;
l2=l2->next;
}
// head variable is to store the head of resultant linked list-
ListNode *head;
head=res;
// while both list contains elements-
while(l1!=NULL && l2!=NULL){
// ListNode *x = new ListNode() works but this doesn't
ListNode y(0);
ListNode *x = &y;
if(l1->val<l2->val){
x->val=l1->val;
l1=l1->next;
}else{
x->val=l2->val;
l2=l2->next;
}
res->next = x;
res = x;
}
// if list1 has some elements left-
while(l1!=NULL){
// ListNode *x = new ListNode() works but this doesn't
ListNode y(0);
ListNode *x = &y;
x->val=l1->val;
res->next=x;
res=x;
l1=l1->next;
}
// if list2 has some elements left-
while(l2!=NULL){
// ListNode *x = new ListNode() works but this doesn't
ListNode y(0);
ListNode *x = &y;
x->val=l2->val;
res->next=x;
res=x;
l2=l2->next;
}
return head;
}
有人可以帮忙吗?
解决方法
也许我们可以在这里简化我们的陈述。
这将简单地通过:
/**
* 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) {}
* };
*/
const static struct Solution {
ListNode* mergeTwoLists(
ListNode* l1,ListNode* l2
) {
ListNode sentinel(0);
ListNode* head = &sentinel;
while (l1 && l2) {
if (l1->val < l2->val) {
head->next = l1;
l1 = l1->next;
} else {
head->next = l2;
l2 = l2->next;
}
head = head->next;
}
head->next = l1 ? l1 : l2;
return sentinel.next;
}
};
由于我们使用的是Sentinel Node,因此我们最终将返回sentinel.next
而不是head
。
参考文献
- 有关其他详细信息,请参见Discussion Board,在这里您可以找到许多具有各种languages且已被广泛接受的解决方案,包括低复杂度算法和渐近runtime / {{ 3}}分析memory,1 。
自动变量dummy
既是造成问题的原因,又是不必要的。
合并两个列表仅意味着从已经分配的其他节点中制作节点链。由于您没有列表“包装器”(即同时包含节点链和其他信息(例如计数,尾指针等)的对象),这仅仅是因为合并节点链的一种做法,这需要单个目标指针和枚举指针到指针来确定结果。
ListNode* mergeTwoLists(ListNode* l1,ListNode* l2)
{
ListNode *res = nullptr;
ListNode **pp = &res;
while (l1 && l2)
{
if (l1->val < l2->val)
{
*pp = l1;
pp = &l1->next;
l1 = l1->next;
}
else
{
*pp = l2;
pp = &l2->next;
l2 = l2->next;
}
}
// one of the lists will have elements left. chain that
// to the list-end and we're done.
*pp = l1 ? l1 : l2;
return res;
}
就是这样。值得一提的一件事。这将真正合并两个输入列表。含义:作为参数传递的调用方的l1
和l2
指针实际上不再具有任何意义,应立即丢弃。现在,原始两个列表的节点将合并为一个列表,该列表将作为此函数的结果返回。如果您要在创建合并时对输入列表进行复制,则可以采用其他策略,但是在您陈述的问题中我看不到有此要求的证据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。