From 185ef9fcb0e59f13e9ee0ccb261693cdaddebab0 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 23 Feb 2021 21:07:19 +0800 Subject: import(solutions): Move leetcode solutions to subdir. --- .../solutions/leetcode/rust/src/add_two_numbers.rs | 160 +++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 works/solutions/leetcode/rust/src/add_two_numbers.rs (limited to 'works/solutions/leetcode/rust/src/add_two_numbers.rs') diff --git a/works/solutions/leetcode/rust/src/add_two_numbers.rs b/works/solutions/leetcode/rust/src/add_two_numbers.rs new file mode 100644 index 0000000..d2ca858 --- /dev/null +++ b/works/solutions/leetcode/rust/src/add_two_numbers.rs @@ -0,0 +1,160 @@ +use super::Solution; + +/******************** provided code ********************/ +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +/******************** my code ********************/ + +use std::ptr::NonNull; + +struct List { + head: Option>, + tail: Option>>, +} + +impl List { + fn new() -> List { + List { + head: None, + tail: None, + } + } + + fn append(&mut self, val: i32) { + let node = Some(Box::new(ListNode::new(val))); + unsafe { + match self.tail { + None => { + self.head = node; + self.tail = Some(NonNull::from(self.head.as_mut().unwrap())); + } + Some(mut t) => { + let last_node = t.as_mut(); + last_node.next = node; + self.tail = Some(NonNull::from(last_node.next.as_mut().unwrap())); + } + } + } + } + + fn to_result(self) -> Option> { + self.head + } +} + +impl Solution { + pub fn add_two_numbers( + l1: Option>, + l2: Option>, + ) -> Option> { + let mut l1 = l1; + let mut l2 = l2; + let mut result = List::new(); + let mut carry = false; + + loop { + match l1 { + None => { + while let Some(v) = l2 { + let digit = v.val + if carry { 1 } else { 0 }; + carry = digit > 9; + let digit = digit % 10; + result.append(digit); + l2 = v.next; + } + break; + } + Some(v1) => match l2 { + None => { + let digit = v1.val + if carry { 1 } else { 0 }; + carry = digit > 9; + let digit = digit % 10; + result.append(digit); + l1 = v1.next; + while let Some(v) = l1 { + let digit = v.val + if carry { 1 } else { 0 }; + carry = digit > 9; + let digit = digit % 10; + result.append(digit); + l1 = v.next; + } + break; + } + Some(v2) => { + let digit = v1.val + v2.val + if carry { 1 } else { 0 }; + carry = digit > 9; + let digit = digit % 10; + result.append(digit); + l1 = v1.next; + l2 = v2.next; + } + }, + } + } + + if carry { + result.append(1); + } + + return result.to_result(); + } +} + +#[cfg(test)] +mod test { + use super::{List, ListNode, Solution}; + + trait IntoList { + fn into_list(self) -> Option>; + } + + trait IntoVec { + fn into_vec(self) -> Vec; + } + + impl IntoList for Vec { + fn into_list(self) -> Option> { + let mut list = List::new(); + for i in self { + list.append(i); + } + list.to_result() + } + } + + impl IntoVec for Option> { + fn into_vec(self) -> Vec { + let mut result = Vec::new(); + let mut node = self; + while let Some(v) = node { + result.push(v.val); + node = v.next; + } + result + } + } + + #[test] + fn test() { + assert_eq!( + Solution::add_two_numbers(vec![2, 4, 3].into_list(), vec![5, 6, 4].into_list()) + .into_vec(), + vec![7, 0, 8] + ); + assert_eq!( + Solution::add_two_numbers(vec![9, 9, 9].into_list(), vec![1].into_list()).into_vec(), + vec![0, 0, 0, 1] + ); + } +} -- cgit v1.2.3