合并k个排序列表不适用于负值C#
问题是: 给您一个由k个链表组成的数组,每个链表按升序排序。 将所有链接列表合并为一个已排序的链接列表并返回它。 一个成功的输入和输出工作示例是:合并k个排序列表不适用于负值C#,c#,list,merge,C#,List,Merge,问题是: 给您一个由k个链表组成的数组,每个链表按升序排序。 将所有链接列表合并为一个已排序的链接列表并返回它。 一个成功的输入和输出工作示例是: Input: lists = [[1,4,5],[1,3,4],[2,6]] Output: [1,1,2,3,4,4,5,6] Explanation: The linked-lists are: [ 1->4->5, 1->3->4, 2->6 ] merging them into one sorted
Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
1->4->5,
1->3->4,
2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6
我的代码的问题是,它不适用于负值,但适用于正值。
例如输入->[2],[1],-1]]输出->[1,2]
public class Solution {
public ListNode MergeKLists(ListNode[] lists) {
if (lists.Length == 0) return null;
var newlist = new ListNode();
var result = newlist;
for(int i=0; i<lists.Length; i++)
{
if(lists[i] !=null)
newlist = MergeTwoLists(lists[i], newlist);
}
return result.next;
}
private ListNode MergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null)
return l2;
if (l2 == null)
return l1;
if (l1.val <= l2.val)
{
l1.next = MergeTwoLists(l1.next, l2);
return l1;
}
else
{
l2.next = MergeTwoLists(l1, l2.next);
return l2;
}
}
}
公共类解决方案{
公共ListNode合并列表(ListNode[]列表){
if(lists.Length==0)返回null;
var newlist=newlistnode();
var结果=新列表;
对于(int i=0;i从根本上讲,代码的问题在于使用非空列表来初始化算法。也就是说,您将newlist
设置为单个ListNode
对象。您还没有提供完整的代码示例,但可能这是一个至少有两个成员的类,val
和next
。在C#中,这两个成员最初都有其默认值,这意味着您在开始合并任何内容之前,先从列表[0]
开始
还请注意,当您在合并循环中修改newlist
变量时,返回的是结果。下一个变量。这似乎是试图跳过您首先在newlist
列表中输入的错误include0
值。但在负值示例中,它会导致让您跳过合并正确放置在其前面的0
值和-1
值
在您的示例[[2],[1],-1]]
中,这意味着当合并循环完成时,您有newlist
引用列表[-1,0,1,2]
。但是result
指向该列表的第二个元素(原始0
-值节点),为您提供[0,1,2]
。然后返回该节点的下一个节点,该节点生成[1,2]
事实是,MergeTwoLists()
您显示的方法已经处理空列表,即空值列表。不清楚是什么促使您使用非空列表初始化算法,也不清楚是什么促使您保留第二个变量来引用同一节点。如果您没有执行后者,您的问题可能会更容易注意到,当然还有ole错误是由前者引起的
您应该从已有的代码中删除这两个方面。将newlist
初始化为null
,而不是为其创建新节点,并将result
变量全部删除:
公共ListNode合并列表(ListNode[]列表){
var newlist=null;
for(int i=0;i
注意:您也不需要检查lists.Length==0
。如果lists.Length
为0
,则将跳过循环,在这种情况下,固定版本仅返回null
作为空列表,没有它也可以正常工作
更一般地说:大多数情况下,bug是通过更改代码甚至删除代码来修复的。如果你养成了通过添加代码来修复bug的习惯,那么你往往会在已有bug的基础上添加一个新bug
我承认,这条规则不是一条硬性的、100%可靠的规则。但多年来它对我很有用。阅读有关调试代码的提示。您的示例是否适用于[[3]、[2]、[1]]
?我怀疑它不会,因此专门查看负值将导致您走上错误的道路,因为可能存在更严重的错误。提示:您的“基本”列表(即新列表
)从已经在其中的一个节点开始。该节点中的val
是什么?将这一知识与一个完全不同的事实结合起来:当您在代码中操作newlist
时,返回结果。下一步
,而不是方法中的newlist.next
。关于这两个事实,请注意,您从这是一个非空列表。您似乎试图用第二个错误来抵消该错误,即返回结果。下一个而不是新列表。这些错误组合在一起会产生您看到的结果。@code学徒:您的示例可以很好地工作。对于负值,代码实际上是被破坏的,结果是两个comp代码中完全不同的错误,这些错误部分地相互平衡,以隐藏合并到结果中的任何负数。