Rust leetcode 初级算法 字符串 代码汇总

反转字符串

最简单的解决方法!

 s.reverse();

 当然也可以自己写!

 let len = s.len();
 let mut t: char;
 for i in 0..len / 2 {
 t = s[i];
 s[i] = s[len - i - 1];
 s[len - i - 1] = t;
 }

整数反转,如果是leet 上写 在 i32前加std 例如 std::i32::MAX, 官方推荐直接i32

 if x > i32::MAX - 1 || x < i32::MIN || x == i32::MIN {
        return 0;
    }
    let mut x: i64 = x as i64;
    let mut newnum: i64 = 0;
    while x != 0 {
        newnum = newnum * 10 + x % 10 as i64;
        x /= 10;
        if newnum > i32::MAX as i64 || newnum < i32::MIN as i64 {
            return 0;
        }
    }
    return newnum as i32;

字符串中的第一个唯一字符

首先创建一个装下所有字母的数组,然后记录出现了几次,类似查重复,之后在迭代一下原字符串,

如果这个字符只出现一次,就返回。第一次迭代为了记录次数,第二次迭代是保证顺序的情况下找出只出现一次的。

    if s == "" {
        return 0;
    }
    let mut index = 0;
    let mut array = vec![0; 26];
    for c in s.bytes() {
        if array[(c - 97) as usize] != 0 {
            array[(c - 97) as usize] = array[(c - 97) as usize] + 1;
            continue;
        }
        array[(c - 97) as usize] = 1;
    }
    for c in s.bytes() {
        if array[(c - 97) as usize] == 1 {
            return index;
        }
        index = index + 1;
    }
    return -1;

有效的字母异位词

和上一道题差不多,首先能装下字母的数组,在第一个字符串出现+1,下一个字符串出现-1,最后判断是否等于0;

iter.zip(iter)是把两个迭代器压缩到一起,然后一起迭代,就和切两根黄瓜一样,就是并排切的意思。

    if s == t {
        return true;
    }
    if s.len() != t.len() {
        return false;
    }
    let s = s.bytes();
    let t = t.bytes();
    let mut v = vec![0; 26];
    // for _ in 0..s.len() {
    //     let st = s.next().unwrap() as usize;
    //     let vt = t.next().unwrap() as usize;
    //     v[st - 97] = v[st - 97] + 1;
    //     v[vt - 97] = v[vt - 97] - 1;
    // }
    for (a, b) in s.zip(t) {
        v[a as usize - 97] = v[a as usize - 97] + 1;
        v[b as usize - 97] = v[b as usize - 97] - 1;
    }
    for e in v.iter() {
        if *e != 0 {
            return false;
        }
    }
    return true;

验证回文串

什么是回文串,简单来说就是,正着读和翻过来读是一样的,就是比较下标 [i] 和 [len-i -l] 这一对下标是否相等;

感受一下Rust的优雅!

    let chars = s
        .chars()
        .filter(|x| x.is_ascii_alphanumeric())
        .map(|x| x.to_ascii_lowercase())
        .collect::<Vec<char>>();
    for (a, b) in chars[0..(chars.len() / 2)].iter().zip(chars.iter().rev()) {
        if a != b {
            return false;
        }
    }
    true

 字符串转换整数(atoi)

我的思路是使用match去匹配字符,有效的字符加到字符串,其中要考虑 " " +  -  0 ,这四种字符和其他字符,每当+ - 出现,另外紧接着的不是数字就结束,出现空格就结束循环,但是一旦出现 0 + - 这些字符,就要标记已经出现可以解析的字符串了,

然后就有了下面的垃圾代码,建议,跑一些,去看看别人怎么写,下面的代码有时候是0ms 有时候是4ms。

    let mut result = String::new();
   // 这个标志位是正负号,在最后的结果会乘以这个标志位 let mut bz_fuhao
= 0;
   // 这是开始的标志位,意味着0 + -后面可能出现可解析的字符串 let mut bz_kaishi
= 0; for c in s.chars() { match c {
       // 首先清除空格
' ' => {
         // 但是开始标志位变化,在出现空格就要结束循环
if bz_kaishi != 0 { break; } continue; }
       // 0在有效数字前是不添加到结果里的,但是0出现标志着开始收集字符了
'0' => { if result == "" { bz_kaishi = 1; continue; } if result != "" { result.push(c); } }
       // 这就是正常收集字符
'1'..='9' => { bz_kaishi = 1; result.push(c); }
       // 符号位出现
'-' => {
         // 如果开始收集字符了,但是又出现 - 就要结束
if bz_kaishi != 0 { break; }          // 收集的字符不是空出现 - 也要结束 if result != "" { break; }
         // 表示一旦收集了一个 - 号,再次出现结束循环
if bz_fuhao != 0 { break; }
         // 收集的字符是空的时候出现 - 号 ,之后就收集
if result == "" { bz_fuhao = -1; bz_kaishi = 1; continue; } }
        // 和减号类似
'+' => { if bz_kaishi != 0 { break; } if result != "" { break; } if bz_fuhao != 0 { break; } if result == "" { bz_fuhao = 1; bz_kaishi = 1; continue; } }
        // 出现其他字符直接结束 _
=> break, } } // 2147483647 -2147483648
  // 如果未出现 + 要把符号位替换为1;
if bz_fuhao == 0 { bz_fuhao = 1; }
  // 判断长度
if result.len() > 10 && bz_fuhao == 1 { return 2147483647; } if result.len() > 10 && bz_fuhao == -1 { return -2147483648; }
  // 只要解析的时候不溢出就行 match result.parse::
<i128>() { Ok(o) => { if o * bz_fuhao < -2147483648 { return -2147483648; } if o * bz_fuhao > 2147483647 { return 2147483647; } return (o * bz_fuhao) as i32; } Err(_) => return 0, }

实现strStr()

这个就是 短字符串在长字符串能滑动几下到头,简单说一下就是,一个长度为7的箱子,你有一个长度为6的小箱子,

从头滑动,滑动一次就到头了,如果是5长度就要滑动2次就到头了,想一下有几个位置状态开始一个加上滑动的次数。

len_h - len_n + 1 就是长字符串可以切割出来的字符。每次切掉 短字符串的长度去比较。

        if needle == ""||haystack == needle{
            return 0;
        }
        let len_h = haystack.len();
        let len_n = needle.len();
        let mut haystack = haystack;
        if len_h < len_n {
            return -1
        }
        for i in 0..len_h-len_n+1{
            if haystack.split_at(len_n).0 == needle{
                return i as i32
            }
            haystack = haystack.split_at(1).1.into();
        }
        return -1;

外观数列

解析先知道什么是外观数列,然后自己看代码吧,我也迷糊。

        if  n == 1 {
            return "1".into();
        }
        let mut res = String::new();
        let str_t = Solution::count_and_say(n-1);
        let len = str_t.len();
        let mut t = 0;
        for i in 1..len+1 {
            if  i == len{
                res.push_str(&(i - t).to_string());
                res.push_str(str_t.get(t..t+1).unwrap());
                return res;
            }else if str_t.get(i..i+1) != str_t.get(t..t+1){
                res.push_str(&(i - t).to_string());
                res.push_str(str_t.get(t..t+1).unwrap());
                t = i;
            } 
        }
        res

最长公共前缀

首先声明一个结束的标志位,思路就是随便找一个字符串,最好是第一个字符串,然后迭代它,每次比较一个字符,判断和其他的字符串同位置的是否相同,

不相同就结束,然后截取结束标志位之前的字符。注意在for循环外返回的需要加1,要不然截取不完全。

        let len  = strs.len();
        if len == 0 {
            return "".into();
        }
        if len  == 1 {
            return strs[0].clone();
        }
        let len0 = strs[0].len();
        if len0 == 0 {
            return "".into();
        }
        let mut t = 0;
        for i in 0..len0{
                t =i;
                let strs0t = strs[0].get(i..i+1).unwrap_or_default();
                if strs0t == ""{
                    return strs[0].get(0..t).unwrap().into(); 
                }
                for j in 1..len {
                    if 0 == strs[j].len(){
                        return "".into(); 
                    }
                    let strsit = strs[j].get(i..i+1).unwrap_or_default();
                    if strs0t == ""{
                        return strs[0].get(0..t).unwrap().into(); 
                    }
                    if strs0t == strsit {
                        continue
                    }else{
                        return strs[0].get(0..t).unwrap().into(); 
                    }
                }      
        }
        return  strs[0].get(0..t+1).unwrap().into(); 

到这里就结束了,之前一个算法一个博客浪费空间,感觉还是和在一起好点,方便看。

原文地址:https://www.cnblogs.com/Addoil/p/13433361.html