这篇文章是rust解决算法问题的第四篇,感兴趣的同学可以去jibinbin 的个人主页 - 动态 - 掘金 (juejin.cn)查看其他文章,话不多说,直接进入正题。
无重复字符的最长子串这道题是我今天下午在小程序codetop上看到的热度第二名的问题,就想着实现一下rust的版本,这里先放一下之前写的js版本的,感兴趣的小伙伴可以浏览一下。
js版本
var lengthOfLongestSubstring = function(s) {
let m = 0;
let arr = [];
for(let i = 0;i < s.length;i++){
let index = arr.indexOf(s[i]);
if(index != -1){
arr.splice(0,index+1);
}
arr.push(s[i]);
m = Math.max(arr.length,m);
}
return m;
};
实现思路
创建一个空数组用于存放无重复的字符数组,遍历字符串s,如果当前元素已经存在于数组中,找到索引,删除数组的首元素索引值+1次,并把当前元素推入数组,比较并保存最大值,遍历结束后返回最大值即可。放两张测试用例的截图。(这里只展示个人思路,想要了解其他解法的同学可以点击无重复字符的最长子串 题解 - 力扣(LeetCode) (leetcode-cn.com))
rust版本(已通过leetcode)
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
let mut vec:Vec<char> = Vec::new();
let mut max = 0;
for item in s.chars(){
let mut index = Solution::index_of(item,&vec);
if index != 0 {
while index > 0 {
vec.remove(0);
index -= 1;
}
}
vec.push(item);
max = if vec.len() > max { vec.len() } else { max };
}
max as i32
}
fn index_of(c:char,vec:&Vec<char>) -> i32 {
let mut num = 0;
for (i,&item) in vec.iter().enumerate() {
if item == c {
num = i+1;
}
}
num as i32
}
}
总结
1
首先一个就是rust没有Array.prototype.indexOf() - JavaScript | MDN (mozilla.org)这种很方便的api可以使用,于是,我就自己写了一个简易的替代函数,实现思路也比较简单,不懂iter和enumerate的话,可以看看我的rust实现全排列 - 掘金 (juejin.cn)
2
第二个就是关于rust删除可变数组元素的方法,目前我了解到的只有Vec in std::vec - remove和Vec in std::vec - pop,pop就很简单嘛,从可变数组末尾删除一个元素,例如:
remove的话,需要传递一个参数,代表你要删除那个数字的下标,但是我们再使用remove方法的时候需要注意,可变数组是在不断调整的,可能不会按照你预想的那样,按照顺序一个一个删除,例如,我们可能会想要删除可变数组的前两个值,于是写了下面的代码:
按照预想,我们最终得到的应该是[3,4]才对,可是得到的结果却是[2,4],原因就在于可变数组vec已经发生变化了。
正确的一种代码如下: