【发布时间】:2020-11-30 22:42:07
【问题描述】:
请帮我找出我的代码有什么问题 (1)。
给你一个包含 N 个节点的单链表,其中每个节点下一个指向它的下一个节点。您还将获得 M 个随机指针,其中您将获得 M 个表示两个节点 a 和 b 的对,即 a->arb = b。
任务是完成函数copyList(),它接受一个参数作为要克隆的链表的头,并且应该返回克隆的链表的头。 注意:如果它们是未给出任意指针的任何节点,则默认为 null。
我尝试为上述问题编写代码..但它不起作用
// { Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
void print(Node *root) {
Node *temp = root;
while (temp != NULL) {
int k;
if (temp->arb == NULL)
k = -1;
else
k = temp->arb->data;
cout << temp->data << " " << k << " ";
temp = temp->next;
}
}
Node *copyList(Node *head);
void append(Node **head_ref, Node **tail_ref, int new_data) {
Node *new_node = new Node(new_data);
if (*head_ref == NULL) {
*head_ref = new_node;
} else
(*tail_ref)->next = new_node;
*tail_ref = new_node;
}
bool validation(Node *head, Node *res, Node *cloned_addr,
Node *generated_addr) {
if (generated_addr == cloned_addr) return false;
Node *temp1 = head;
Node *temp2 = res;
int len1 = 0, len2 = 0;
while (temp1 != NULL) {
len1++;
temp1 = temp1->next;
}
while (temp2 != NULL) {
len2++;
temp2 = temp2->next;
}
/*if lengths not equal */
if (len1 != len2) return false;
temp1 = head;
temp2 = res;
while (temp1 != NULL) {
if (temp1->data != temp2->data) return false;
if (temp1->arb != NULL and temp2->arb != NULL) {
if (temp1->arb->data != temp2->arb->data) return false;
} else if (temp1->arb != NULL and temp2->arb == NULL)
return false;
else if (temp1->arb == NULL and temp2->arb != NULL)
return false;
temp1 = temp1->next;
temp2 = temp2->next;
}
return true;
}
/* Driver program to test above function*/
int main() {
int T, i, n, l, k;
Node *generated_addr = NULL;
/*reading input stuff*/
cin >> T;
while (T--) {
generated_addr = NULL;
struct Node *head = NULL, *tail = NULL;
cin >> n >> k;
for (i = 1; i <= n; i++) {
cin >> l;
append(&head, &tail, l);
}
for (int i = 0; i < k; i++) {
int a, b;
cin >> a >> b;
Node *tempA = head;
int count = -1;
while (tempA != NULL) {
count++;
if (count == a - 1) break;
tempA = tempA->next;
}
Node *tempB = head;
count = -1;
while (tempB != NULL) {
count++;
if (count == b - 1) break;
tempB = tempB->next;
}
// when both a is greater than N
if (a <= n) tempA->arb = tempB;
}
/*read finished*/
generated_addr = head;
Node *res = copyList(head);
Node *cloned_addr = res;
cout << validation(head, res, cloned_addr, generated_addr) << endl;
}
return 0;
}
// } Driver Code Ends
/* the node structure is as follows
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
*/
// Should return the head of the copied linked list the
// output will be 1 if successfully copied
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node*q=head;
Node*clone=new Node(q->data);
clone->next=0;
clone->arb=q->arb;
Node*p=clone;
Node*r=q;
q=q->next;
while(q)
{
r->next=p;
p->next=new Node(q->data);
p=p->next;
p->next=0;
p->arb=q->arb;
r=q;
q=q->next;
}
r->next=p;
p=clone;
while(p)
{
if(p->arb)
p->arb=p->arb->next;
p=p->next;
}
return clone;
}
【问题讨论】:
-
当我在现实世界的问题中有这样的任务时,我使用了
std::map<Node*, Node*>。在第一次迭代中,我克隆了节点:对于每个原始节点,创建一个副本,但将原始指针存储在Node::arb中。 (我将其称为平面副本。)此外,地图中填充了原始节点作为键,新节点(副本)作为值。在第二次迭代中,复制节点的Node::arbs 使用映射替换以进行查找。 (如果Node::arb指向地图中未找到的内容,则回退到默认空值。) -
供参考,问题位于leetcode.com/problems/copy-list-with-random-pointer/description。这里有很多代码——超过了完成任务所需的代码。我建议重新制定策略,如果允许额外空间,我建议使用哈希映射。
-
如果你想挑战自己,尝试不使用容器(例如
map<...>),不使用除Node之外的结构或类,正如上面定义的那样,并且在 O(n) 中。
标签: c++ data-structures linked-list