- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
给定 2 个已经排序的单向链表,合并这些列表。
例子:
列表 1: 1 2 3 5 7
列表 2: 0 4 6 7 10
---> 0 1 2 3 4 5 6 7 7 10
尽管解决方案非常简单,并且使用或不使用递归(如 http://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ 参见方法 3)有几种不同的问题实现方式,
我想知道这个实现的 O big 复杂性是什么:
例如:继续前面的例子,如果已经添加了 4,我可以安全地从 4 开始下一个比较:
列表 1:0 1 2 3 4 5 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(m + n)
,而不是O(m * n)
。
既然有了最后插入节点的指针,从那开始寻找插入下一个节点的地方,总共有多少
current = current->next
sortedInsert
中的操作最多为 m + n - 1
(结果的长度减一)。插入操作(重新链接 next
指针)的次数为 n
(第二个列表的长度)。对于每个比较
current->next->data < newNode->data
下一个操作要么是插入,要么是current = current->next
,所以比较次数最多
m + 2*n - 1
假设结果列表以第一个列表中的 m_0
个元素开始,然后是第二个列表中的 n_1
个元素,然后是第二个列表中的 m_1
个元素第一个,n_2
来自第二个,...,n_r
来自第二个,最后是 m_r
来自第一个。 m_0
和 m_r
可以为 0,所有其他数字都严格为正数。
将 n_1
block 的第一个元素与 m_0
block 的每个元素和 m_1
block 的第一个元素进行比较。该 block 的所有其他元素与第二个列表中的前一个元素进行比较,m_1
block 的第一个元素 [除非 r = 1
和 m_1 = 0
,在这种情况下比较较少]。
这使得 m_0 + 1 + (n_1 - 1)*2 = m_0 + 2*n_1 - 1
比较(或更少)。
对于后面的n_k
block ,第一个元素与n_(k-1)
block 的最后一个元素进行比较,m_的所有元素(k-1)
block ,以及 m_k
block 的第一个元素 [如果存在的话]。该 block 的其他元素都与列表 2 中的前一个元素进行比较,m_k
block 的第一个元素[如果存在],使得
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;
从循环中测试。
关于algorithm - 合并两个列表的大 O 复杂性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16495034/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!