这篇文章是rust解决算法问题的第七篇,感兴趣的掘友可以去jibinbin 的个人主页 - 动态 - 掘金 (juejin.cn)查看其他文章,话不多说,直接进入正题。
409. 最长回文串 - 力扣(LeetCode) (leetcode-cn.com)也是一道难度为简单的问题,下午的时候实现了js版本,晚上按照思路搞定了rust版本。
实现思路
这个问题我的思路比较简单,回文串的话,个数可能为奇数,比如“aba”,也可能为偶数,比如“aabb”,所以要想得到最长的回文串,一定是特定条件下最大次数的累计。首先利用hashmap存储下来每个字符出现的次数,对出现次数进行从大到小的排序。之后遍历数组,如果出现次数大于1且为偶数,则直接加上该次数;如果出现次数大于1且为奇数,则直接加上该次数并减1(至于为什么要减一,原因是如果现在直接加上该次数,后面可能出现的奇数都无法添加,导致不是最长的)。最后判断现在最大回文串的长度是否小于字符串的长度,如果是则证明肯定有字母出现次数为奇数次,再判断其是否为偶数,如果是则说明还可以再添加一个字母,否则不能添加。
js版本
var longestPalindrome = function(s) {
let map = new Map();
let sum = 0;
for(let i = 0;i < s.length;i++){
if(map.has(s[i])){
map.set(s[i],map.get(s[i]) + 1);
}else{
map.set(s[i],1);
}
}
let arr = [...map.values()].sort(function(a,b){
return b-a;
});
for(let i = 0;i < arr.length;i++){
if(arr[i] > 1){
if(arr[i] % 2 != 0){
sum += arr[i] - 1;
}else{
sum += arr[i];
}
}
}
if(sum < s.length && sum % 2 == 0){
sum += 1;
}
return sum;
};
rust版本
use std::collections::HashMap;
impl Solution {
pub fn longest_palindrome(s: String) -> i32 {
let mut nums = HashMap::new();
let mut vec = vec![];
let mut sum = 0;
for item in s.chars(){
let count = nums.entry(item).or_insert(0);
*count += 1;
}
for (_key,value) in nums{
vec.push(value);
}
vec.sort(); // 想要了解排序的掘友可以查看文章末尾的第二个资料
vec.reverse();
for item in &vec{
if *item > 1 {
if item % 2 == 0{
sum += item;
}else{
sum += item - 1;
}
}
}
if sum < s.len() && sum % 2 == 0 {
sum += 1;
}
sum as i32
}
}
问题以及解决思路
在写rust版本的解法时,有统计字母出现次数这一步骤,想想也是很简单的嘛,判断哈希映射中是否有该键,如果有就更新其对应的值,否则插入相应的键值对。可是我却遇到了一点警告。
if nums.contains_key(&item){
match nums.get(&item){
Some(val) => {
nums.insert(item,val + 1);
}
None => {
}
}
}else{
nums.insert(item,1);
}
通过查阅资料,我解锁了两种解决办法:
第一种
使用hashmap的新的api,在哈希映射中存储键和关联值 - Rust 程序设计语言 简体中文版 (kaisery.github.io),这里有具体的例子,放一下截图,感兴趣的掘友可以点击链接阅读文章
第二种
根据警告的原因和下图得知,
val应该是不可变的,而我为了更新出现次数,进行了加一操作,导致了这个问题,那么有没有一种方法能够返回可变的引用呢?很快,我发现了HashMap in std::collections - get_mut。然后,我将get改为了get_mut,在我以为万事大吉的时候,报错了(emmmmm)。
错误的原因也很直接,不能在同一时间多次将其作为可变变量借用。这个问题,我之前也遇到过,在rust实现接雨水 - 掘金 (juejin.cn)这篇博客里面解释过原因以及解决思路,想要了解的掘友可以点击上方链接查看,也可以查看官方文档的解释引用与借用 - Rust 程序设计语言 简体中文版 (kaisery.github.io)
知道了错误的原因,解决就很容易了,同一时间不能多次将其作为可变变量借用,那我在第二次借用之前用一次不就行了,顺利通过leetcode
查阅资料
HashMap in std::collections - Rust (rust-lang.org)
结语
如果您在阅读的过程中,发现了问题或者有更好的想法,欢迎留言,感谢!!!