给定已排序的两个单链表,合并这些列表。
示例:
list1: 1 2 3 5 7
list2: 0 4 6 7 10
---
尽管这个解决方案非常简单,并且有几个不同的问题实现,不管是否使用递归(如下所示http://www.geeksforgeeks.org/merge-two-sorted-linked-lists/见方法3),
我想知道这个实现有多复杂:
例:继续上一个示例如果已经添加了4,我可以安全地从4开始下一次比较:
列表1:0 1 2 345 7
列表2:6 7 10
现在将6与4进行比较,而不是与1 2 3 4进行比较。。。。
如果我将一个元素与第一个列表中的所有元素进行比较,它将是O(m*n),m=#list2和n=#list1,但是考虑到这种“优化”,复杂性是什么?
实施:
// Insert a new node in a sorted list
int sortedInsert(struct ListNode **head, struct ListNode* newNode) {
int headUpdated = 0;
struct ListNode *current;
// The list is empty or the new element has to be added as first element
if (*head == NULL || (*head)->data >= newNode->data) {
newNode->next = *head;
*head = newNode;
headUpdated = 1;
}
else {
// Locate the node before the point of insertion
current = *head;
while (current->next != NULL && current->next->data < newNode->data)
current = current->next;
newNode->next = current->next;
current->next = newNode;
}
return headUpdated;
}
struct ListNode *mergeLists(struct ListNode *head1, struct ListNode *head2) {
if (head1 == NULL)
return head2;
if (head2 == NULL)
return head1;
// Store the node in the first list where to start the comparisons
struct ListNode *first = head1;
while (head2) {
struct ListNode *head2Next = head2->next;
printf("Adding %d starting comparison from %d\n", head2->data, first->data);
if (sortedInsert(&first, head2))
head1 = first;
first = head2;
head2 = head2Next;
}
return head1;
}
实际上,这里的合并算法是O(mn)
,而不是O(mn)
。
由于您有一个指向上一个插入节点的指针,并从该指针开始查找插入下一个节点的位置,因此
current = current->next
sortedInrett
中的操作至多为m n-1
(结果长度减1)。插入操作(重新链接下一个
指针)的数量为n
(第二个列表的长度)。对于每个比较
current->next->data < newNode->data
下一个操作要么是插入,要么是当前=当前-
m + 2*n - 1
假设结果列表从第一个列表的
m_0
元素开始,然后从第二个列表的n_1
元素开始,然后从第一个列表的m_1
开始,从第二个列表的n_2
开始n\u r
从第二个开始,然后最后从第一个开始m\u r
m_0
和m_r
可能为0,所有其他数字都严格为正。
将
n_1
块的第一个元素与m_0
块的每个元素以及m_1
块的第一个元素进行比较。将该块的所有其他元素与第二个列表中的前一个元素以及m_1
块的第一个元素进行比较[除非r=1
和m_1=0
,在这种情况下比较较少]。
这使得
m1(n1-1)*2=m2*n1-1
比较(或更少)。
对于后面的
n_k
块,将第一个元素与n_k(k-1)
块的最后一个元素、m_k(k-1)
块的所有元素以及m_k
块的第一个元素(如果存在)进行比较。块的其他元素都与列表2中的前一个元素进行比较,m_k
块的第一个元素[如果存在的话],这使得
1 + m_(k-1) + 1 + (n_k - 1)*2 = m_(k-1) + 2*n_k
比较(或更少)。由于所有比较都至少涉及第二个列表中的一个元素,因此比较的总数最多为
m_0 + 2*n_1 - 1 + m_1 + 2*n_2 + m_2 + 2*n_3 + ... + m_(r-1) + 2*n_r <= m + 2*n - 1.
我们可以稍微改进一下
struct ListNode *first = head1;
以及移除
if (!first)
first = head1;
从循环中进行测试。
在最近的一次测试中,我们得到了一个函数来计算未排序的ArrayList中出现了多少个double(不是原语double,而是一个项目出现了两次)。 我正确地确定了Big O复杂度为O(N^2),但由于我错误地确定了全部复杂度,因此只获得了部分学分。函数如下: 在他刚刚发布的考试解决方案中,他给出了这样的解释: 输入集合中有N个项,该方法通过一个缩减步骤反复调用自己,该步骤生成一个新索引N次,直到达
我知道,对于迭代,递增。
问题内容: 我有两个从JSON转换的数据对象。两者都非常复杂,我想以类似于jQuery使用扩展合并两个对象的方式来合并它们。 例 JSON 1: JSON 2: 合并成 用PHP对象解决此问题的最佳方法是什么。 问题答案: 将每个JSON字符串解码为一个关联数组,合并结果并重新编码 更新: 如果您有特定的合并要求,则需要编写自己的合并功能。我在下面写了一篇满足您问题中要求的书。如果您有其他未提及的
rank ▲ ✰ vote url 65 357 50 683 url 合并两个列表 怎样合并两个列表? 例如: listone = [1,2,3] listtwo = [4,5,6] 我期待: mergedlist == [1, 2, 3, 4, 5, 6] 在Python中非常容易. mergedlist = listone + listtwo
我在期中考试中遇到了这个问题,我不确定我的答案是O(n^2)。我想要有解释的答案,谢谢。
我正在学习算法和数据结构课程。 今天,我的教授说下面算法的复杂度是2n。 我一直等到课程结束,走近他,告诉他我真的相信这是一个O(n)算法,我做了计算来证明它,并想给他们看,但他继续说它不是,没有给我任何令人信服的解释。 该算法是递归的,具有以下复杂性: 我计算它是一个,这样: 让我们展开 当T中的项为1时,我们停止,即: n/(2i)=1== 替换后,我们获得 由于该算法是从关于合并排序的课程中