2021年02月03日 : RustでLeetCode
先日も書いた通り
LeetCodeをやっていて、なるべくRustでコードを書くようにしてるのですが、 とにもかくにも、面倒なんですよね……。 たとえば、二分木の問題なんかは、Pythonだと
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
なんてわかりやすい定義なんですが、Rustだと
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None
}
}
}
こうなります。 構造体のようでいて、Option/Rc/RefCellの理解が必須という鬼のような状況です。
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
}
}
}
まぁ、当然のようにOption/Boxの組み合わせとなります。 LeetCodeだとテストとかしたいわけですが、やろうとするとノードが1個しかないような木でも 以下みたいな事になります。
#[test]
fn test_case1() {
assert_eq!(
Solution::is_valid_bst(Some(Rc::new(RefCell::new(TreeNode::new(1))))),
true
);
}
ツライ……。
ということで、上記を
#[test]
fn test_case1() {
assert_eq!(
Solution::is_valid_bst(TreeNode::from_str("[1]")),
true
);
}
のように書けるようにするべく頑張ってみようかと ちょっと頑張りだしました 。 調べたら、誰かもう作ってるだろうけど、まぁこれも鍛錬です。
で、ひとまず、コードはとても効率的ではなさそうなのですが、上記のようなテストが書けるようになった……と思ったんですが、 おもいっきりclippyに怒られて泣いています 。 clippyっていうのは、Rustのlintなんですね……。 怒られてるのはごもっともなのでなんとかしたいのですが、ジェネリクス使ったparse()のエラー処理で困っています。 誰かオシエテ。 どうせleetcodeではノードにはi32しかこなさそうなので、i32で作ってしまえばよかったかしら……。
ちなみに、これを作っていたため、昨日は dailyの問題(Treeの問題) を しっかり解きそびれました!! うぉーー。