Skip to content

Commit

Permalink
Add problem 2130: Maximum Twin Sum of a Linked List
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Feb 7, 2024
1 parent d2d22b2 commit 6035b55
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,7 @@ pub mod problem_2114_maximum_number_of_words_found_in_sentences;
pub mod problem_2119_a_number_after_a_double_reversal;
pub mod problem_2124_check_if_all_as_appears_before_all_bs;
pub mod problem_2129_capitalize_the_title;
pub mod problem_2130_maximum_twin_sum_of_a_linked_list;

#[cfg(test)]
mod test_utilities;
37 changes: 37 additions & 0 deletions src/problem_2130_maximum_twin_sum_of_a_linked_list/in_place.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::data_structures::ListNode;

pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl Solution {
pub fn pair_sum(head: Option<Box<ListNode>>) -> i32 {
let mut head = head;
let mut list = Vec::new();

while let Some(node) = head {
list.push(node.val);
head = node.next;
}

let (left, right) = list.split_at(list.len() / 2);

left.iter().zip(right.iter().rev()).map(|(x, y)| x + y).max().unwrap()
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn pair_sum(head: Option<Box<ListNode>>) -> i32 {
Self::pair_sum(head)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
22 changes: 22 additions & 0 deletions src/problem_2130_maximum_twin_sum_of_a_linked_list/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::data_structures::ListNode;

pub mod in_place;
pub mod reverse_half;

pub trait Solution {
fn pair_sum(head: Option<Box<ListNode>>) -> i32;
}

#[cfg(test)]
mod tests {
use super::Solution;
use crate::test_utilities;

pub fn run<S: Solution>() {
let test_cases = [(&[5, 4, 2, 1] as &[_], 6), (&[4, 2, 2, 3], 7), (&[1, 100_000], 100_001)];

for (head, expected) in test_cases {
assert_eq!(S::pair_sum(test_utilities::make_list(head.iter().copied())), expected);
}
}
}
54 changes: 54 additions & 0 deletions src/problem_2130_maximum_twin_sum_of_a_linked_list/reverse_half.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::data_structures::ListNode;

pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::iter;
use std::mem;

impl Solution {
fn make_iter(list: Option<&ListNode>) -> impl Iterator<Item = &ListNode> {
iter::successors(list, |node| node.next.as_deref())
}

pub fn pair_sum(head: Option<Box<ListNode>>) -> i32 {
let mut head = head;
let length = Self::make_iter(head.as_deref()).count();
let mut node = &mut head;

for _ in 0..length / 2 {
node = &mut node.as_deref_mut().unwrap().next;
}

let mut right = None;
let mut maybe_node = node.take();

while let Some(mut node) = maybe_node {
maybe_node = mem::replace(&mut node.next, right);
right = Some(node);
}

Self::make_iter(head.as_deref())
.zip(Self::make_iter(right.as_deref()))
.map(|(left, right)| left.val + right.val)
.max()
.unwrap()
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn pair_sum(head: Option<Box<ListNode>>) -> i32 {
Self::pair_sum(head)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}

0 comments on commit 6035b55

Please sign in to comment.