I'm solving a problem from Leetcode and encountered the fact that Rust won't let me execute it efficiently. What am I doing wrong? I know about the book article about references and borrowing and would like to know how to solve this problem despite the peculiarities of the language.
I am trying to create one reference for a vec that should change and another for a vec that will not change. Rust won't let me do that. The program works, but only when using .clone(), which will be very slow and not necessary (last_row does not change anywhere, only the values are derived from there).
Here is the working code:
use std::cmp; fn minimum_total(mut triangle: Vec<Vec<i32>>) -> i32 { for i in (0..triangle.len()-1).rev() { // from penultimate (last - 1) to first let last_row = & triangle[i+1].clone(); let current_row = &mut triangle[i]; for j in 0..current_row.len() { current_row[j] = cmp::min(last_row[j], last_row[j+1]) + current_row[j]; } } triangle[0][0] } fn main() { println!("{}", minimum_total(vec![vec![2],vec![3,4],vec![6,5,7],vec![4,1,8,3]])); } As you can see, I used .clone() to fix the borrow checker errors that show up when you try to write a program using references:
use std::cmp; fn minimum_total(mut triangle: Vec<Vec<i32>>) -> i32 { for i in (0..triangle.len()-1).rev() { // from penultimate (last - 1) to first let current_row = &mut triangle[i]; let last_row = &triangle[i+1]; for j in 0..current_row.len() { current_row[j] = cmp::min(last_row[j], last_row[j+1]) + current_row[j]; } } triangle[0][0] } fn main() { println!("{}", minimum_total(vec![vec![2],vec![3,4],vec![6,5,7],vec![4,1,8,3]])); } Terminal:
error[E0502]: cannot borrow `triangle` as immutable because it is also borrowed as mutable --> src\main.rs:6:25 | 5 | let current_row = &mut triangle[i]; | -------- mutable borrow occurs here 6 | let last_row = &triangle[i+1]; | ^^^^^^^^ immutable borrow occurs here 7 | for j in 0..current_row.len() { | ----------------- mutable borrow later used here For more information about this error, try `rustc --explain E0502`. However, when trying to write a program poorly everything works without any problems:
use std::cmp; fn minimum_total(mut triangle: Vec<Vec<i32>>) -> i32 { for i in (0..triangle.len()-1).rev() { // from penultimate (last - 1) to first for j in 0..triangle[i].len() { triangle[i][j] = cmp::min(triangle[i+1][j], triangle[i+1][j+1]) + triangle[i][j]; } } triangle[0][0] } fn main() { println!("{}", minimum_total(vec![vec![2],vec![3,4],vec![6,5,7],vec![4,1,8,3]])); }
triangle[][]?trianglewhile editing it using two different references. Your double for loop code is probably the better way to do it. Just because it is a double for loop does not mean it is automatically worse