Skip to content

Latest commit

 

History

History
119 lines (109 loc) · 3.42 KB

0002.两数相加.md

File metadata and controls

119 lines (109 loc) · 3.42 KB

解题关键点

  • 列表的第一项对应大数的个位
  • 注意进位,注意当两个数加完之后可能还有进位

代码

// 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]);