leetcode简单题4 N.14 最长公共前缀 rust描述

// ["flower","flow","flight"]  "fl"
// ["dog","racecar","car"]  ""
// 纵向扫描 同一个索引扫描其他所有字符
pub fn longest_common_prefix(strs: Vec<String>) -> String {
    if strs.is_empty() {//如果向量不包含任何元素,则返回 true
        return String::new(); //返回空字符串
    }

    let mut prefix = String::new();

    for i in 0..strs[0].len() { // 第一个字符串的长度索引
        let c = strs[0].chars().nth(i).unwrap();//nth 迭代器中选取 返回option枚举类型 unwrap解包 也就是第i个字符
        for s in &strs[1..] { //切片  遍历了其他所有 i是上层
            if i >= s.len() || s.chars().nth(i).unwrap() != c {//索引比其余字符的长度长 或 遍历的单个字符不相同
                return prefix;
            }
        }   
        prefix.push(c);//相同就添加
    }

    prefix
}
// 横向扫描 单个字符完全扫描完,在接着扫描下一个字符
pub fn longest_common_prefix2(strs: Vec<String>) -> String {
    if strs.is_empty() {
        return String::new();
    }

    let mut prefix = strs[0].clone();//直接克隆一个

    for s in &strs[1..] {
        while !s.starts_with(&prefix) {//匹配字符串前缀 ! 非运算
            prefix.pop(); // 直到完全相等  其实条件也可以用是否相同来判断
            if prefix.is_empty() {
                return String::new();//空了就是没有公共前缀
            }
        }
    }
    prefix
}
//二分法
pub fn longest_common_prefix3(strs: Vec<String>) -> String {
    fn common_prefix(left: &str, right: &str) -> String {//两个字符串相匹配
        let min_length = left.len().min(right.len());//两个数更小的那个
        for i in 0..min_length { //遍历到最小公共长度
            if left.chars().nth(i).unwrap() != right.chars().nth(i).unwrap() {//不相等
                return left[..i].to_string();//返回所在下标构成的切片
            }
        }
        left[..min_length].to_string()//最小公共长度切片
    }

    fn longest_common_prefix_recursive(strs: &[String], l: usize, r: usize) -> String {
        if l == r {//
            return strs[l].clone();
        } else {
            let mid = (l + r) / 2;//向零取整,所以 7为例 0 6  0 3 4 6  8为例 0 7  0 3 4 7 前面会至少相同数量,奇数时候会多一个 只有一个的时候返回本身
            let lcp_left = longest_common_prefix_recursive(strs, l, mid);// 向左
            let lcp_right = longest_common_prefix_recursive(strs, mid + 1, r);// 向右
            return common_prefix(&lcp_left, &lcp_right);// 1 与 2的结果 3与4的结果 在一起比一次结果
        }
    }

    if strs.is_empty() {
        return String::new();
    }
    longest_common_prefix_recursive(&strs, 0, strs.len() - 1)//左右索引
}
fn main() {
    assert_eq!(longest_common_prefix(vec![String::from("flower"),String::from("flow"),String::from("flight")]), "fl");
    assert_eq!(longest_common_prefix(vec![String::from("dog"),String::from("racecar"),String::from("car")]), "");

    assert_eq!(longest_common_prefix2(vec![String::from("flower"),String::from("flow"),String::from("flight")]), "fl");
    assert_eq!(longest_common_prefix2(vec![String::from("dog"),String::from("racecar"),String::from("car")]), "");

    assert_eq!(longest_common_prefix3(vec![String::from("flower"),String::from("flow"),String::from("flight")]), "fl");
    assert_eq!(longest_common_prefix3(vec![String::from("dog"),String::from("racecar"),String::from("car")]), "");

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值