Rust 刷leetcode 第二题

题目描述

力扣

// Definition for singly-linked list.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
    pub val: i32,
    pub next: Option<Box<ListNode>>,
}



struct Solution {}

impl Solution {
    pub fn add_two_numbers(
        l1: Option<Box<ListNode>>,
        l2: Option<Box<ListNode>>,
    ) -> Option<Box<ListNode>> {
        let mut number1 = 0;
        let mut number2 = 0;
        if let Some(ref box_list_node) = l1 {
            number1 = to_number(box_list_node);
        }
        if let Some(ref box_list_node) = l2 {
            number2 = to_number(box_list_node);
        }

        println!("number1 = {}", number1);
        println!("number2 = {}", number2);

        println!("sum = {}", number1 + number2);

        let ret = num_to_list_node(number1 + number2);

        return ret;
    }
}

pub fn to_number(list_node: &ListNode) -> i32 {
    let mut ret: Vec<i32> = Vec::new();

    let mut t = list_node;
    loop {
        ret.push(t.val);
        match t.next {
            Some(ref temp) =>  {t = temp;}
            None => {
                break;
            }
        }
    }
    let mut sum = 0;
    let mut acc = 1;

    for i in ret {
        sum += i * acc;
        acc *= 10;
    }
    return sum;
}

pub fn num_to_list_node(number:  i32) -> Option<Box<ListNode>>{
    
    let mut list_node1 = ListNode::new(0);
    let mut ptr = &mut list_node1;

    let mut t = number;

    loop {
        if t > 9 {
            let temp = t % 10;
            print!("  = {}", temp);

            ptr.next = Some(Box::new(ListNode::new(temp)));

            if let Some(ref mut box_node) = ptr.next {
                ptr = box_node;
            }

            t = t / 10;

        }else {
            print!("  = {}", t);
            ptr.next = Some(Box::new(ListNode::new(t)));

            break;
        }
    }
    println!();
    println!("ret = {}", to_number(&list_node1));

    return list_node1.next;

}

impl ListNode {
    #[inline]
    pub fn new(val: i32) -> Self {
        ListNode { next: None, val }
    }

    // 想修改节点,必须返回可变借用
    pub fn get_last_mut(&mut self) -> &mut Self {
        match self.next {
            Some(ref mut temp) => {
                return temp.get_last_mut();
            }
            None => {
                return self;
            }
        }

    }


    // 追加节点
    pub fn append(&mut self, val: i32) {
        let _node = ListNode::new(val);
        self.get_last_mut().next = Some(Box::new(_node));
    }
}


// [9]
// [1,9,9,9,9,9,9,9,9,9]
fn main() {
    let mut list_node = ListNode::new(9);

    let mut list_node2 = ListNode::new(1);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);
    list_node2.append(9);

    Solution::add_two_numbers(Some(Box::new(list_node)), Some(Box::new(list_node2)));

}

这个思路很简单,先将链表转换为i32,加起来之后再将i32转换成链表,不过这个思路是有问题的,会有溢出的问题。需用原始的链表来解决。

初学Rust确实有点困难,最终参考了他人的解题重写如下

impl Solution {
    pub fn add_two_numbers(
        l1: Option<Box<ListNode>>,
        l2: Option<Box<ListNode>>,
    ) -> Option<Box<ListNode>> {
        let mut dummy = None;
        let mut curr = &mut dummy;
        let mut t = (l1, l2, 0, 0); // l1,l2,sum,offset

        loop {
            t = match t {
                (None, None, _, 0) => break,
                (None, None, _, offset) => (None, None, offset, 0),
                (Some(list), None, _, offset) | (None, Some(list), _, offset) => (
                    list.next,
                    None,
                    (list.val + offset) % 10,
                    (list.val + offset) / 10,
                ),
                (Some(l1), Some(l2), _, offset) => (
                    l1.next,
                    l2.next,
                    (l1.val + l2.val + offset) % 10,
                    (l1.val + l2.val + offset) / 10,
                ),
            };
            *curr = Some(Box::new(ListNode::new(t.2)));
            curr = &mut curr.as_mut().unwrap().next;
        }
        dummy
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Rust 是一种现代的编程语言,特别适合处理内存安全和线程安全的代码。在 LeetCode 中,链表是经常出现的目练习类型,Rust 语言也是一种非常适合处理链表的语言。接下来,本文将从 Rust 语言的特点、链表的定义和操作,以及 RustLeetCode 中链表目的练习等几个方面进行介绍和讲解。 Rust 语言的特点: Rust 是一种现代化的高性能、系统级、功能强大的编程语言,旨在提高软件的可靠性和安全性。Rust 语言具有如下几个特点: 1. 内存安全性:Rust 语言支持内存安全性和原语级的并发,可以有效地预防内存泄漏,空悬指针以及数据竞争等问,保证程序的稳定性和可靠性。 2. 高性能:Rust 语言采用了“零成本抽象化”的设计思想,具有 C/C++ 等传统高性能语言的速度和效率。 3. 静态类型检查:Rust 语言支持静态类型检查,可以在编译时检查类型错误,避免一些运行时错误。 链表的定义和操作: 链表是一种数据结构,由一个个节点组成,每个节点保存着数据,并指向下一个节点。链表的定义和操作如下: 1. 定义:链表是由节点组成的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。 2. 操作:链表的常用操作包括插入、删除、查找等,其中,插入操作主要包括在链表首尾插入节点和在指定位置插入节点等,删除操作主要包括删除链表首尾节点和删除指定位置节点等,查找操作主要包括根据数据元素查找节点和根据指针查找节点等。 RustLeetCode 中链表目的练习: 在 LeetCode 中,链表是常见的目类型,而 Rust 语言也是一个非常适合练习链表目的语言。在 Rust 中,我们可以定义结构体表示链表的节点,使用指针表示节点的指向关系,然后实现各种操作函数来处理链表操作。 例如,针对 LeetCode 中的链表目,我们可以用 Rust 语言来编写解法,例如,反转链表,合并两个有序链表,删除链表中的重复元素等等,这样可以更好地熟悉 Rust 语言的使用和链表的操作,提高算法和编程能力。 总之,在 Rust 中处理链表是非常方便和高效的,而 LeetCode 中的练习也是一个非常好的机会,让我们更好地掌握 Rust 语言和链表数据结构的知识。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值