英文:
How can I use Rust to CLONE a linked list?
问题
I'm a rookie in Rust, and currently I'm actively using Rust to code LeetCode practice.
Now I'm working on this one, Copy List with Random Pointer, where nobody has even provided a Rust version answer.
I tried for a while but then I realized it's insanely hard for me to copy even a simple linked list in Rust.
Thanks for the help from @cafce25 that we can directly use .clone()
to implement it, which is amazing. However, I'm wondering if there is any implementation that we don't need to use such a mighty weapon .clone()
so that I could delve from this point.
Could anyone give me a favor? Thank you pretty much.
Some interfaces are provided as below and please feel free to modify function signatures.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
pub fn new(val: i32) -> Self {
ListNode {
val,
next: None,
}
}
pub fn copyList(head: &Option<Box<ListNode>>) -> Option<Box<ListNode>> {
todo!();
}
}
英文:
I'm a rookie in Rust, and currently I'm actively using Rust to code LeetCode practice.
Now I'm working on this one, Copy List with Random Pointer, where nobody has even provided a Rust version answer.
I tried for a while but then I realised it's insanely hard for me to copy even a simple linked list in Rust.
Thanks for the help from @cafce25 that we can directly use .clone()
to implement it, which is amazing. However, I'm wondering if there is any implementation that we don't need to use such a mighty weapon .clone()
so that I could delve from this point.
Could anyone give me a favour? Thank you pretty much.
Some interfaces are provided as below and please feel free to modify function signatures.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
pub fn new(val: i32) -> Self {
ListNode {
val,
next: None,
}
}
pub fn copyList(head: &Option<Box<ListNode>>) -> Option<Box<ListNode>> {
todo!();
}
}
答案1
得分: 2
Sure, here's the translated content:
不过,我在想是否有一种实现方式,我们不需要使用如此强大的
clone()
方法,这样我就可以从这一点深入。
首先,将 copyList
实际上获取列表节点本身的引用似乎是合理的,更符合惯用命名的是 copy_list
:
pub fn copy_list(head: &ListNode) -> ListNode {
todo!()
}
(末尾没有 ;
,因为我们希望返回一个结果,分号会使函数返回 ()
)。第一步是(不一定需要,但很有用)对参数进行模式匹配,我们也知道最终要返回一个 ListNode
,所以让我们在那里构建它:
pub fn copy_list(head: &ListNode) -> ListNode {
let ListNode { val, next } = head;
let copied_next = todo!();
ListNode { val: todo!(), next: copied_next }
}
剩下的是计算 copied_next
(好吧,还有 val
,但它要简单得多)。我不会为你提供完整的代码,但提供一些提示:
- 考虑
next
和copied_next
的类型; - 您可以对
next
进行模式匹配,或者使用Option::map
和Box::map
; - 您将在模式匹配或
map
的参数内的某个地方递归调用copy_list
。
(而且简单地使用 next.clone()
也可以工作,并且大致上就是生成的 clone()
函数所做的事情,这也是它克隆整个列表的原因。)
英文:
> However, I'm wondering if there is any implementation that we don't need to use such a mighty weapon .clone() so that I could delve from this point.
First of all, it seems reasonable for copyList
to actually take a reference to a list node itself, and the more idiomatic name is copy_list
:
pub fn copy_list(head: &ListNode) -> ListNode {
todo!()
}
(no ;
at the end because we want to return a result, and the semicolon would make the function return ()
). The first step is (not necessarily, but it's useful) to pattern-match the argument, and we also know we want to return a ListNode
at the end, so let's construct it there:
pub fn copy_list(head: &ListNode) -> ListNode {
let ListNode { val, next } = head;
let copied_next = todo!();
ListNode { val: todo!(), next: copied_next }
}
What remains is to calculate copied_next
(ok, and val
, but it's much simpler). I won't give you the full code for it, but some hints:
- Consider the types of
next
andcopied_next
; - You can use either pattern matching on
next
orOption::map
andBox::map
; - You'll call
copy_list
recursively somewhere inside that pattern match ormap
's argument.
(And simply next.clone()
would work too, and is approximately what the generated clone()
function does, which is why it clones the entire list.)
答案2
得分: 0
以下是您要翻译的内容:
感谢@Alexey Romanov的启发。经过数小时的调试,我实现了一种简单的克隆链表的方法,如下所示:
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
pub fn new(val: i32) -> Self {
ListNode {
val,
next: None,
}
}
pub fn clone_linked_list(mut head: &Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut dummy = Box::new(ListNode::new(-1));
let mut pre = &mut dummy;
while let Some(node) = head {
let new_node = Box::new(ListNode::new(node.val));
pre.next.replace(new_node);
pre = pre.next.as_mut().unwrap();
head = &node.next;
}
dummy.next
}
}
请随时提出任何建议。非常感谢。
英文:
Thanks for the inspiration from @Alexey Romanov. After several hours of debugging, I implemented a plain way to clone a linked list as below:
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
pub fn new(val: i32) -> Self {
ListNode {
val,
next: None,
}
}
pub fn clone_linked_list(mut head: &Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut dummy = Box::new(ListNode::new(-1));
let mut pre = &mut dummy;
while let Some(node) = head {
let new_node = Box::new(ListNode::new(node.val));
pre.next.replace(new_node);
pre = pre.next.as_mut().unwrap();
head = &node.next;
}
dummy.next
}
}
Please feel free to give any suggestions. Thank you a lot.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论