- 列表的第一项对应大数的个位
- 注意进位,注意当两个数加完之后可能还有进位
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
impl Solution {
// Option 表示可选类型
pub fn add_two_numbers(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
// 创建结果的前置项
let mut result = Some(Box::new(ListNode::new(0)));
// 使用 as_mut() 获取可变引用
let mut node = result.as_mut();
// 在一行中声明多个变量的语法
let (mut l1, mut l2, mut carry) = (l1, l2, 0);
// is_some() 用于判断 Optional 的值是否存在
while l1.is_some() || l2.is_some() {
let mut sum = carry;
// 使用 Some(变量名) 获取 Option 存在的值
if let Some(l) = l1 {
sum += l.val;
l1 = l.next;
};
if let Some(l) = l2 {
sum += l.val;
l2 = l.next;
};
carry = sum / 10;
if let Some(n) = node {
n.next = Some(Box::new(ListNode::new(sum % 10)));
node = n.next.as_mut();
}
}
if carry == 1 {
// .unwrap() 直接返回 Option 存在的值
node.unwrap().next = Some(Box::new(ListNode::new(carry)));
}
// 代码块的最后一行如果只有不加分号的左手表达式,相当于返回值
result.unwrap().next
}
}
其实 result 和 node 不必为 Option 的,稍微优化了一下代码,减少了一些不必要的 if
pub fn add_two_numbers(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut result = Box::new(ListNode::new(0));
let mut node = result.as_mut();
let (mut l1, mut l2, mut carry) = (l1, l2, 0);
while l1.is_some() || l2.is_some() {
let mut sum = carry;
if let Some(l) = l1 {
sum += l.val;
l1 = l.next;
};
if let Some(l) = l2 {
sum += l.val;
l2 = l.next;
};
carry = sum / 10;
node.next = Some(Box::new(ListNode::new(sum % 10)));
node = node.next.as_mut().unwrap();
}
if carry == 1 {
node.next = Some(Box::new(ListNode::new(carry)));
}
result.next
}
// 这里需要定义两个辅助函数,用于 ListNode 和 Vec 的类型转换
pub fn vec_to_list(v: Vec<i32>) -> Option<Box<ListNode>> {
let mut result = Some(Box::new(ListNode::new(0)));
let mut node = result.as_mut();
for i in v {
if let Some(n) = node {
n.next = Some(Box::new(ListNode::new(i)));
node = n.next.as_mut();
}
}
result.unwrap().next
}
pub fn list_to_vec(mut l: Option<Box<ListNode>>) -> Vec<i32> {
let mut v = Vec::new();
while let Some(l1) = l {
v.push(l1.val);
l = l1.next;
}
v
}
assert_eq!(list_to_vec(add_two_numbers(vec_to_list(vec![0]), vec_to_list(vec![0]))), vec![0]);
assert_eq!(list_to_vec(add_two_numbers(vec_to_list(vec![1]), vec_to_list(vec![9, 9, 9]))), vec![0, 0, 0, 1]);
assert_eq!(list_to_vec(add_two_numbers(vec_to_list(vec![2, 3, 7]), vec_to_list(vec![5, 9, 2]))), vec![7, 2, 0, 1]);