【问题标题】:Check if two single linked lists contain the same data检查两个单链表是否包含相同的数据
【发布时间】:2012-04-12 16:12:36
【问题描述】:

我们必须检查两个给定的链表是否包含相同的数据。这种情况下的顺序无关紧要,这意味着{1,3,2}{2,1,3} 相同。我认为我们应该引入一个新变量counter=0 并执行以下过程:

while(node1->next!=NULL)
{
    int value=node1->value;
    if(contains(node2,value)){
        counter++;
    }

    node1=node1->next;

    if(counter== number of elements in node 1) 
        return true; 
    else return false;
}

另一种方法是对两个列表进行排序并逐个节点进行比较。哪一个是最优的?在第一种情况下,它需要 O(n^2) 次操作,而在第二种情况下,如 Nlog(N)+O(N),(如果我们使用归并排序)。我的想法是对的吗?还是有其他最优方法?

【问题讨论】:

  • 真正的答案是:如果必须这样做,首先不要使用链表!
  • 你对内存复杂度有限制吗?-如果没有,可以在 O(n) 内存和 O(m+n) 时间内实现它,当 n 和 m 是列表的长度时. 可以通过使用 hashmap 或或某种位图来实现
  • 使用哈希图怎么样?我对重复元素持怀疑态度。
  • @Jerry Coffin 我明白了,只是编程书上的问题

标签: c++ linked-list compare


【解决方案1】:

在您发布的两种方法中,第二种更好。但我建议你hashing

首先散列第一个链表。

在散列时检查第二个列表。

这样一共可以在O(n)时间内完成。

【讨论】:

  • 我喜欢你的回答,但重复的部分需要一点开销吗?
  • 如果第二个列表是第一个列表的子集,那不会给出误报吗?
  • 基本上,散列中的冲突是 OP 中的“计数器”。所以很少有人听到。
  • 这也是另一种极端情况,以键作为元素值作为出现次数的哈希图?
  • @James,可以在散列时使用计数器轻松计算出。 @Morpheus,计数器可以帮助处理重复项。因为,比较的最终输出只是一个truefalse
【解决方案2】:

如果链接列表中的值允许,您可以使用第一个链接的值创建一个直方图,然后遍历第二个列表,在执行过程中递减直方图条目。如果最后直方图只包含零,那么它们是相同的。

例如,如果 list1 包含 {1, 3, 4, 2, 4},则直方图将是(从零开始)[0, 1, 1, 1, 2]。

如果 list2 包含 {1, 3, 2, 4},则递减后的直方图将是 [0, 0, 0, 0, 1]。

运行时间为 O(m + n)

【讨论】:

  • 所以对于直方图我应该引入另一个空间是吗?例如位数组或位向量
  • 除非您确定任一列表中没有重复项,否则您不能使用位数组
【解决方案3】:

这个解决方案需要相同的时间复杂度,但还是要好一点!

{
 while(node1->next != NULL)
 {
    if(!contains(node2, node1->value)){
        return false;
    }
    node1 = node1->next;
 }
 return true;
}

【讨论】:

    【解决方案4】:

    你可以把数字打印成一个字符串,然后对字符串进行排序,这样一切都按正确的顺序排列

    编辑:这只是你的其他方式更好的建议

    【讨论】:

      【解决方案5】:

      这里有一个绝对可行的递归解决方案....

      int CompareLists(Node *headA, Node* headB)
      {
      
      if (headA == NULL && headB == NULL)     
      {  return 1;  }
      if (headA == NULL && headB != NULL)  
      {  return 0;  }
      if (headB != NULL && headB == NULL)  
      {  return 0;  }
      if (headA->data != headB->data)
      {  return 0;  }
      
      return CompareLists(headA->next, headB->next);  
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-16
        • 1970-01-01
        • 1970-01-01
        • 2019-11-07
        相关资源
        最近更新 更多