每天一道Rust-LeetCode,2019-06-03

坚持每天一道题,刷题学习Rust.

原题

题目描述

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定的有序链表: [-10, -3, 0, 5, 9],

一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

  0
 / \

-3 9

/ /

-10 5

解题过程

这是一个递归求解问题:

首先把链表从中间切开,那么这时候主体是一个相对平衡的二叉树

左边,右边分别像第一步一样递归求解即可.

impl Solution {
    pub fn sorted_list_to_bst(head: Option<Box<ListNode>>) -> Option<Rc<RefCell<TreeNode>>> {
        let v = Solution::list_to_vec(head);
        let nodes = v.as_slice();
        Solution::build_tree(nodes)
    }
    fn build_tree(nodes: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
        if nodes.len() == 0 {
            return None;
        }
        let left = nodes.len() / 2;
        let right = nodes.len() / 2 + 1;
        let mut leftNode: Option<Rc<RefCell<TreeNode>>> = None;
        let mut rightNode = None;
        if left > 0 {
            leftNode = Solution::build_tree(&nodes[0..left]);
        }
        if right <= nodes.len() - 1 {
            rightNode = Solution::build_tree(&nodes[right..nodes.len()])
        }
        Some(Rc::new(RefCell::new(TreeNode {
            val: nodes[nodes.len() / 2],
            left: leftNode,
            right: rightNode,
        })))
    }
    fn list_to_vec(head: Option<Box<ListNode>>) -> Vec<i32> {
        let mut rhead = head.as_ref();
        let mut v = Vec::new();
        while let Some(h) = rhead {
            v.push(h.val);
            rhead = h.next.as_ref();
        }
        v
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::share::build_list_node;
    use crate::share::build_tree;
    use crate::share::NULL;
    #[test]
    fn test_sorted_list_to_bst() {
        let l1 = build_list_node(&vec![-10, -3, 0, 5, 9]);
        let t = build_tree(&vec![0, -3, 9, -10, NULL, 5]);
        //        println!("t={:?}", t);
        //        println!("sorted={:?}", Solution::sorted_list_to_bst(l1));
        assert_eq!(Solution::sorted_list_to_bst(l1), t);

        let l1 = build_list_node(&vec![3, 5, 8]);
        let t = build_tree(&vec![5, 3, 8]);
        //        println!("t={:?}", t);
        //        println!("sorted={:?}", Solution::sorted_list_to_bst(l1));
        assert_eq!(Solution::sorted_list_to_bst(l1), t);
    }
}

一点感悟

Tree里虽然用到了Rc,RcCell等,但是这里并不需要直接使用,因为只是构建,并不试用.

RefCell定义

RefCell接口的定义

impl<T: ?Sized> RefCell<T> {

pub fn borrow(&self) -> Ref<T> { } 
pub fn try_borrow(&self) -> Result<Ref<T>,BorrowError> {}
 pub fn borrow_mut(&self) -> RefMut<T> { } 
 pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError> { }
     pub fn get_mut(&mut self) -> &mut T { }

如何选择Cell和RefCell?

如果你只需要整体性地存⼊、取出T,那么就选 Cell。如果你需要有个可读写指针指向这个T修改它,那么就选RefCell。

其他

欢迎关注我的github,本项目文章所有代码都可以找到.