Two Sum Leetcode Rust Solution?
I've been trying to use rust to answer some questions in leetcode. While I feel it hard to deal with linked-list, especially for question Two Sum. How should I deal with the problem of moved value?
This is a piece of code can pass the test.
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
pub fn add_two_numbers(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
tmp = match tmp.as_mut(){
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum /10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0{
return res;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
While it can't pass local compile, having error message
error[E0506]: cannot assign to `tmp` because it is borrowed
--> empty.rs:109:13
|
109 | tmp = match tmp.as_mut(){
| ^ --- borrow of `tmp` occurs here
| _____________|
| |
110 | | Some(_n) => {
111 | | let sum = node1.val + node2.val + _n.val;
112 | | let carry = sum /10;
... |
121 | | _ => unreachable!(),
122 | | };
| |_____________^ assignment to borrowed `tmp` occurs here
error[E0499]: cannot borrow `*tmp` as mutable more than once at a time
--> empty.rs:109:25
|
109 | tmp = match tmp.as_mut(){
| ^^^ mutable borrow starts here in previous iteration of loop
...
126 | }
| - mutable borrow ends here
error[E0505]: cannot move out of `res` because it is borrowed
--> empty.rs:115:28
|
105 | let mut tmp = &mut res;
| --- borrow of `res` occurs here
...
115 | return res;
| ^^^ move out of `res` occurs here
I thought I might understand a little bit since tmp is a mutable reference to res, then res is moved. But how could I keep the head of a linked list while at the meantime, keep adding tails to it?
linked-list rust
add a comment |
I've been trying to use rust to answer some questions in leetcode. While I feel it hard to deal with linked-list, especially for question Two Sum. How should I deal with the problem of moved value?
This is a piece of code can pass the test.
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
pub fn add_two_numbers(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
tmp = match tmp.as_mut(){
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum /10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0{
return res;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
While it can't pass local compile, having error message
error[E0506]: cannot assign to `tmp` because it is borrowed
--> empty.rs:109:13
|
109 | tmp = match tmp.as_mut(){
| ^ --- borrow of `tmp` occurs here
| _____________|
| |
110 | | Some(_n) => {
111 | | let sum = node1.val + node2.val + _n.val;
112 | | let carry = sum /10;
... |
121 | | _ => unreachable!(),
122 | | };
| |_____________^ assignment to borrowed `tmp` occurs here
error[E0499]: cannot borrow `*tmp` as mutable more than once at a time
--> empty.rs:109:25
|
109 | tmp = match tmp.as_mut(){
| ^^^ mutable borrow starts here in previous iteration of loop
...
126 | }
| - mutable borrow ends here
error[E0505]: cannot move out of `res` because it is borrowed
--> empty.rs:115:28
|
105 | let mut tmp = &mut res;
| --- borrow of `res` occurs here
...
115 | return res;
| ^^^ move out of `res` occurs here
I thought I might understand a little bit since tmp is a mutable reference to res, then res is moved. But how could I keep the head of a linked list while at the meantime, keep adding tails to it?
linked-list rust
add a comment |
I've been trying to use rust to answer some questions in leetcode. While I feel it hard to deal with linked-list, especially for question Two Sum. How should I deal with the problem of moved value?
This is a piece of code can pass the test.
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
pub fn add_two_numbers(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
tmp = match tmp.as_mut(){
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum /10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0{
return res;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
While it can't pass local compile, having error message
error[E0506]: cannot assign to `tmp` because it is borrowed
--> empty.rs:109:13
|
109 | tmp = match tmp.as_mut(){
| ^ --- borrow of `tmp` occurs here
| _____________|
| |
110 | | Some(_n) => {
111 | | let sum = node1.val + node2.val + _n.val;
112 | | let carry = sum /10;
... |
121 | | _ => unreachable!(),
122 | | };
| |_____________^ assignment to borrowed `tmp` occurs here
error[E0499]: cannot borrow `*tmp` as mutable more than once at a time
--> empty.rs:109:25
|
109 | tmp = match tmp.as_mut(){
| ^^^ mutable borrow starts here in previous iteration of loop
...
126 | }
| - mutable borrow ends here
error[E0505]: cannot move out of `res` because it is borrowed
--> empty.rs:115:28
|
105 | let mut tmp = &mut res;
| --- borrow of `res` occurs here
...
115 | return res;
| ^^^ move out of `res` occurs here
I thought I might understand a little bit since tmp is a mutable reference to res, then res is moved. But how could I keep the head of a linked list while at the meantime, keep adding tails to it?
linked-list rust
I've been trying to use rust to answer some questions in leetcode. While I feel it hard to deal with linked-list, especially for question Two Sum. How should I deal with the problem of moved value?
This is a piece of code can pass the test.
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
pub fn add_two_numbers(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
tmp = match tmp.as_mut(){
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum /10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0{
return res;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
While it can't pass local compile, having error message
error[E0506]: cannot assign to `tmp` because it is borrowed
--> empty.rs:109:13
|
109 | tmp = match tmp.as_mut(){
| ^ --- borrow of `tmp` occurs here
| _____________|
| |
110 | | Some(_n) => {
111 | | let sum = node1.val + node2.val + _n.val;
112 | | let carry = sum /10;
... |
121 | | _ => unreachable!(),
122 | | };
| |_____________^ assignment to borrowed `tmp` occurs here
error[E0499]: cannot borrow `*tmp` as mutable more than once at a time
--> empty.rs:109:25
|
109 | tmp = match tmp.as_mut(){
| ^^^ mutable borrow starts here in previous iteration of loop
...
126 | }
| - mutable borrow ends here
error[E0505]: cannot move out of `res` because it is borrowed
--> empty.rs:115:28
|
105 | let mut tmp = &mut res;
| --- borrow of `res` occurs here
...
115 | return res;
| ^^^ move out of `res` occurs here
I thought I might understand a little bit since tmp is a mutable reference to res, then res is moved. But how could I keep the head of a linked list while at the meantime, keep adding tails to it?
linked-list rust
linked-list rust
asked Jan 3 at 1:18
burytheupsidedownburytheupsidedown
112
112
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Your code compiles as written in stable Rust 2018 (or in nightly Rust 2015 with #![feature(nll)]
).
You can make it compile in stable Rust 2015 with just a few tweaks:
pub fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
// Add this block to limit the scope of tmp.
{
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
// Add braces around tmp to force it to be moved instead of reborrowed.
tmp = match { tmp }.as_mut() {
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum / 10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0 {
// Move the return statement outside the block.
break;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
return res;
}
It probably makes sense why return res
needs to be moved outside the scope of tmp
. The { tmp }
thing is a bit more confusing: it tells the compiler to move tmp
instead of reborrowing it (see this explanation).
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54015194%2ftwo-sum-leetcode-rust-solution%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your code compiles as written in stable Rust 2018 (or in nightly Rust 2015 with #![feature(nll)]
).
You can make it compile in stable Rust 2015 with just a few tweaks:
pub fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
// Add this block to limit the scope of tmp.
{
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
// Add braces around tmp to force it to be moved instead of reborrowed.
tmp = match { tmp }.as_mut() {
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum / 10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0 {
// Move the return statement outside the block.
break;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
return res;
}
It probably makes sense why return res
needs to be moved outside the scope of tmp
. The { tmp }
thing is a bit more confusing: it tells the compiler to move tmp
instead of reborrowing it (see this explanation).
add a comment |
Your code compiles as written in stable Rust 2018 (or in nightly Rust 2015 with #![feature(nll)]
).
You can make it compile in stable Rust 2015 with just a few tweaks:
pub fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
// Add this block to limit the scope of tmp.
{
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
// Add braces around tmp to force it to be moved instead of reborrowed.
tmp = match { tmp }.as_mut() {
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum / 10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0 {
// Move the return statement outside the block.
break;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
return res;
}
It probably makes sense why return res
needs to be moved outside the scope of tmp
. The { tmp }
thing is a bit more confusing: it tells the compiler to move tmp
instead of reborrowing it (see this explanation).
add a comment |
Your code compiles as written in stable Rust 2018 (or in nightly Rust 2015 with #![feature(nll)]
).
You can make it compile in stable Rust 2015 with just a few tweaks:
pub fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
// Add this block to limit the scope of tmp.
{
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
// Add braces around tmp to force it to be moved instead of reborrowed.
tmp = match { tmp }.as_mut() {
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum / 10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0 {
// Move the return statement outside the block.
break;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
return res;
}
It probably makes sense why return res
needs to be moved outside the scope of tmp
. The { tmp }
thing is a bit more confusing: it tells the compiler to move tmp
instead of reborrowing it (see this explanation).
Your code compiles as written in stable Rust 2018 (or in nightly Rust 2015 with #![feature(nll)]
).
You can make it compile in stable Rust 2015 with just a few tweaks:
pub fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut head1 = l1;
let mut head2 = l2;
let mut res = Some(Box::new(ListNode::new(0)));
// Add this block to limit the scope of tmp.
{
let mut tmp = &mut res;
loop {
let node1 = head1.take().unwrap_or(Box::new(ListNode::new(0)));
let node2 = head2.take().unwrap_or(Box::new(ListNode::new(0)));
// Add braces around tmp to force it to be moved instead of reborrowed.
tmp = match { tmp }.as_mut() {
Some(_n) => {
let sum = node1.val + node2.val + _n.val;
let carry = sum / 10;
_n.val = sum % 10;
if node1.next.is_none() && node2.next.is_none() && carry == 0 {
// Move the return statement outside the block.
break;
} else {
_n.next = Some(Box::new(ListNode::new(carry)));
}
&mut _n.next
}
_ => unreachable!(),
};
head1 = node1.next;
head2 = node2.next;
}
}
return res;
}
It probably makes sense why return res
needs to be moved outside the scope of tmp
. The { tmp }
thing is a bit more confusing: it tells the compiler to move tmp
instead of reborrowing it (see this explanation).
edited Jan 4 at 10:38
answered Jan 3 at 4:14
Anders KaseorgAnders Kaseorg
1,790918
1,790918
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54015194%2ftwo-sum-leetcode-rust-solution%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown