这篇文章是rust解决算法问题的第三篇,感兴趣的同学可以去jibinbin 的个人主页 – 动态 – 掘金 (juejin.cn)查看其他文章,话不多说,直接进入正题。
42. 接雨水 – 力扣(LeetCode) (leetcode-cn.com)这道题是面试的热门问题,leetcode上面有各路大神的解题思路,在这里我就不赘述了。
以下代码已通过leetcode:
代码
impl Solution {
pub fn trap(height: Vec<i32>) -> i32 {
let mut sum: i32 = 0;
for i in 1..height.len() - 1 {
let mut left: i32 = 0;
let mut right: i32 = 0;
for j in (0..i+1).rev() {
left = if height[j] > left { height[j] } else { left };
}
for j in i..height.len() {
right = if height[j] > right { height[j] } else { right };
}
let mut num: i32 = if left > right { right } else { left };
num = num - height[i];
sum += num;
}
sum
}
}
复制代码
问题以及解决思路
其实写rust版本花费了我挺长时间,我大概是从下午四点初开始写,思路是有的,但是写rust总是让我头疼得很,这次也不例外。四点到五点之间一直在修复各种编译错误,修到最后直接panic了(被自己菜到无语。。。)。代码的话比较简单,造成编写时间差的缘由主要在于思路,在for循环中,分别向左向右遍历,左边的话是逆向遍历的,我首先想到的是翻转函数,整体数组切片,切片函数再翻转,在我写rust实现全排列 – 掘金 (juejin.cn)的时候,从切片当中尝到了好处,于是这个我也按照之前的思路走,出现了引用和借用的问题,而且我一直修复不了。。。。。。。
let mut vec = vec![4,6,8,10];
let v1 = &mut vec[0..2];
let v2 = &vec[2..];
v1.reverse();
println!("{:?},{:?}",v1,v2);
复制代码
报的错误是:
大致意思是vec不能同时是可变的,也是不可变的,然后,我想的是,既然不能同时可变和不可变,那就把第二个改变mut不就行了
let v2 = &mut vec[2..];
复制代码
立马运行,可是又出了错误
这个刚开始让我百思不得其解,于是我去查看了引用与借用 – Rust 程序设计语言 简体中文版 (kaisery.github.io),其中有一句话,可变引用有一个很大的限制:在同一时间只能有一个对某一特定数据的可变引用。举得例子刚刚好,和我出的错一模一样,然后我认真地再次看了整篇文章,找到了解决问题的思路
下面是修改后的代码:
let mut vec = vec![4,6,8,10];
let v1 = &mut vec[0..2];
v1.reverse();
println!("{:?}",v1);
let v2 = &vec[2..];
println!("{:?}",v2);
复制代码
不过虽然我解决了这个问题,五点多的时候,我在浏览资料的时候,看到了可变数组的下标取值,就转变了思路,尝试写了写,没想到很快就通过了leetcode,而且代码也很简单。
tip
由于其中有些地方牵扯到取两个值之间的最大值和最小值,自然而然的,我想到了三元表达式,可是rust没有这个,不过,有替代品,也是很轻松实现了大小比较。
- 在rust中,if构造不是语句,而是一个表达式(表达式会返回值)。该值可以是empty类型的(),也可能是实际的值。重点要注意的是,if和else分支必须具有相同的返回值类型。
- 在条件分支中添加分号会改变代码的含义,例如
let res2 = if true { "hhh"; } else { "mmm";};
println!("{:?}",res2);
复制代码
在这种情况下,结果将是一个empty类型的(),这就是我们必须更改println!(“{:?}”,a)表达式的原因。