From 63a998cb7b675f80a46a1d6a482060684cd3dbcd Mon Sep 17 00:00:00 2001 From: "Fernando J. Iglesias Garcia" Date: Sun, 8 Sep 2024 10:03:49 +0900 Subject: [PATCH] Find whether list is in binary tree. --- leetcode/1367.cpp | 45 +++++++++++++++++++++++++ leetcode/1367.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 leetcode/1367.cpp create mode 100644 leetcode/1367.rs diff --git a/leetcode/1367.cpp b/leetcode/1367.cpp new file mode 100644 index 0000000..356094a --- /dev/null +++ b/leetcode/1367.cpp @@ -0,0 +1,45 @@ +#include +#include + +struct list_node { + int val; + list_node *next; + list_node(int x) : val(x), next(nullptr) {} + list_node(int x, list_node *next) : val(x), next(next) {} +}; + +struct tree_node { + int val; + tree_node *left; + tree_node *right; + tree_node(int x) : val(x), left(nullptr), right(nullptr) {} + tree_node(int x, tree_node *left, tree_node *right) : val(x), left(left), right(right) {} +}; + +bool is_subpath_impl(list_node*, tree_node*); +bool is_subpath(list_node* head, tree_node* root) { + if (!root) return false; + return is_subpath_impl(head, root) or is_subpath(head, root->left) or is_subpath(head, root->right); +} +bool is_subpath_impl(list_node* listNode, tree_node* treeNode) { + if (!listNode) return true; + if (!treeNode) return false; + if (listNode->val != treeNode->val) return false; + return is_subpath_impl(listNode->next, treeNode->right) or is_subpath_impl(listNode->next, treeNode->left); +} + +using std::unique_ptr; +using std::make_unique; + +int main() { + unique_ptr ln0 = make_unique(1); + unique_ptr ln1 = make_unique(2, ln0.get()); + unique_ptr list = make_unique(2, ln1.get()); + + unique_ptr leaf = make_unique(1); + unique_ptr l1 = make_unique(2, leaf.get(), nullptr); + unique_ptr l2 = make_unique(2, nullptr, l1.get()); + unique_ptr tree = make_unique(2, l2.get(), nullptr); + + if (!is_subpath(list.get(), tree.get())) throw std::domain_error("Test failed."); +} diff --git a/leetcode/1367.rs b/leetcode/1367.rs new file mode 100644 index 0000000..ca1eea9 --- /dev/null +++ b/leetcode/1367.rs @@ -0,0 +1,84 @@ +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ListNode { + pub val: i32, + pub next: Option> +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { + next: None, + val + } + } +} + +#[derive(Debug, Eq, PartialEq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32, left: Option>>, right: Option>>) -> Self { + TreeNode { + val, + left, + right + } + } +} + +use std::rc::Rc; +use std::cell::RefCell; + +pub fn is_sub_path(head: Option>, root: Option>>) -> bool { + is_sub_path_internal(head.as_ref(), root.as_ref()) +} + +fn is_sub_path_internal(head: Option<&Box>, root: Option<&Rc>>) -> bool { + if root.is_none() { + return false; + } + + let root_ref = root.unwrap().borrow(); + + is_sub_path_impl(head, root) || + is_sub_path_internal(head, root_ref.left.as_ref()) || + is_sub_path_internal(head, root_ref.right.as_ref()) +} + +fn is_sub_path_impl(list_node: Option<&Box>, tree_node: Option<&Rc>>) -> bool { + if list_node.is_none() { + return true; + } + if tree_node.is_none() { + return false; + } + + let list_node = list_node.unwrap(); + let tree_node_ref = tree_node.unwrap().borrow(); + + if list_node.val == tree_node_ref.val { + is_sub_path_impl(list_node.next.as_ref(), tree_node_ref.left.as_ref()) || + is_sub_path_impl(list_node.next.as_ref(), tree_node_ref.right.as_ref()) + } else { + false + } +} + +fn main() { + let mut list = ListNode::new(2); + list.next = Some(Box::new(ListNode::new(2))); + list.next.as_mut().unwrap().next = Some(Box::new(ListNode::new(1))); + + let leaf = TreeNode::new(1, None, None); + let l1 = TreeNode::new(2, Some(Rc::new(RefCell::new(leaf))), None); + let l2 = TreeNode::new(2, None, Some(Rc::new(RefCell::new(l1)))); + let tree = TreeNode::new(2, Some(Rc::new(RefCell::new(l2))), None); + + assert!(is_sub_path(Some(Box::new(list)), Some(Rc::new(RefCell::new(tree))))) +}