Leetcode - solve questions in leetcode by Rust

Overview

leetcode

Solve questions in leetcode by Rust

前言

由于 Rust 写数据结构相关的资料特别少并且理解非常困难,所以专门建了个 Repo 用来记录 Rust 刷 leetcode 的解法并包含心得体会,欢迎 Star 会长期稳定更新。
努力写出最容易理解的 Rust 代码。 https://github.com/zhangyuang/leetcode

注: 以下代码并没有刻意追求最优解,主要目的在于熟悉 Rust 语法以及使用可读性强便于理解的代码来解决问题。欢迎 Star✨ 长期稳定保持更新。

相关资料

官方 API 文档
Rust 程序设计语言中文版

debug in VSCode

建议本地编码时使用 VSCode 自带的 lldb 调试功能来进行断点调试,提升开发效率

// setting.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "name": "Debug",
      "args": [],
      "cwd": "${workspaceFolder}",
      "cargo": {
        "args": [
          "test",
          "--manifest-path=.test_repo/Cargo.toml"
        ],
        "filter": {
          "name": "leetcodebyrust",
          "kind": "lib"
        }
      },
    }
  ]
}

F5/Fn+F5 启动调试

lldb 调试 Rust

我们通过 lldb 来调试 Rust 代码,同样我们会经常需要在 Debug Console 中打印出当前的一些变量值。这里需要特殊配置,根据 VScode LLDB 文档描述 Debug Console 提供两种执行模式。分别是以 lldb commands 模式执行,或者 expressions 表达式的形式执行。

当我们需要进行表达式求值时需要在前面加上 ? 符号。例如 ?foo 打印 foo 的值。

也可以通过 settings.json 中配置 "lldb.consoleMode": "evaluate" 默认启用 evaluate 模式,不再需要输入 ? 符号。此时调用 lldb commands 需要添加 /cmd 开头

分类

链表(linkedList)
二叉树(binaryTree)
动态规划(dynamic programing)
HOT100 🔥

linkedList

链表

Rust 解链表题思路

Go 程序员已经下班 Cpp 程序员还在打断点 Rust 程序员还在编译

Rust 解决数据结构问题相比于其他语言十分的困难,就在于变量所有权的 move(转移)与 borrow(借用)。

遍历链表

通常使用可变引用来遍历, 注意这里需要对 Option<Box<ListNode>> struct 使用 as_ref 或者 as_mut 来进行引用遍历。根据官方文档的解释,我们可以看出 as_ref/as_mut 在这里的作用是 Converts from &Option<T> to Option<&T>

let mut root = &mut head;
while let Some(node) = root {
  let next_node = &mut node.next;
  // 使用as_mut获取next_node的引用,使用&mut获取.next的引用。以此来获取root下一个节点的下一个节点的引用。直接使用unwrap会导致所有权的move
  let next_node_next = &mut next_node.as_mut()?.next;
  // 这里面不能再直接使用head,因为head的所有权已经借给了root,在循环体中未归还
  // other code...
  root = &mut node.next;
}

写法二

while head.as_mut()?.next.is_some() {
    head = &mut head.as_mut()?.next;
}
转移获取链表节点所有权
  • take 方法使用方式见文档
  • Copy 以及 Clone 的区别可查看该文章
// 因为next为Box智能指针存储在堆上的节点,不具备Copy属性,无法直接从堆上转移数据否则会造成多次释放的问题。使用take方法将所有权转移出去,并且在原位置留下了None。
let next_node = node.next.take();

Rust 解决 树 题思路

共享树节点

这里我们尽量不使用 clone 或者 take 来重复获取树节点的所有权,这样会导致性能低下以及影响入参树的数据结构, 这里我们使用 Rc::clone

let root_borrow = root.as_ref().unwrap().borrow();
let left = if root_borrow.left.is_some() {
    Some(Rc::clone(root_borrow.left.as_ref().unwrap()))
} else {
    None
};
let right = if root_borrow.right.is_some() {
    Some(Rc::clone(root_borrow.right.as_ref().unwrap()))
} else {
    None
};

解题代码

皆通过 leetcode 测试用例,可直接粘贴到 leetcode 编辑器中调试,刷题建议由浅入深,按知识点来刷,不要左右横跳。

Easy

简单难度的链表题

回文链表|is_palindrome
反转链表|reverse_list
链表的中间节点|middle_node
删除链表节点|delete_node
删除链表重复节点|delete_duplicates

Medium

中等难度的链表题

两数相加|add_two_numbers
两两交换链表中的节点|swap_pairs
删除链表的倒数第 N 个节点|remove_nth_from_end 合并两个链表|merge_in_between
旋转链表|rotate_right
从链表中删去总和值为零的连续节点|remove_zero_sum_sublists
链表中的下一个更大节点|next_larger_nodes
删除链表重复节点 2|delete_duplicate

Tree

树,二叉树

解题思路

Rust 构造树需要使用 Rc引用计数智能指针以及 RefCell,使得一个数据具有多个可变的所有者。因为一个子节点可能被多个父节点所共享。

Easy

简单难度的树题 二叉搜索树解题思路:中序遍历的结果是递增数组

二叉树的层次遍历 II|level_order_bottom
二叉树的层平均值|average_of_levels
相同的树|is_symmetric
对称二叉树|is_same_tree
平衡二叉树|is_balanced
二叉树的所有路径|binary_tree_paths
二叉树的最小深度|min_depth
左叶子之和|sum_of_left_leaves
二叉搜索树中的众数|find_mode
二叉搜索树中的搜索|search_bst
二叉搜索树的第 k 大节点|kth_largest
二叉搜索树的范围和|range_sum_bst
二叉搜索树节点最小距离|min_diff_in_bst
把二叉搜索树转换为累加树|convert_bst
将有序数组转换为二叉搜索树|sorted_array_to_bst
另一个树的子树|is_subtree
叶子相似的树|leaf_similar
563 二叉树的坡度

Medium

中等难度的树题

二叉树前序遍历|preorder_traversal
二叉树中序遍历|inorder_traversal
二叉树层次遍历|level_order
二叉树展开为链表|flatten
不同的二叉搜索树|num_trees
验证二叉搜索树|is_valid_bst
二叉树的锯齿形层次遍历|zigzag_level_order
最长同值路径|longest_univalue_path
前缀树|Trie
从前序与中序遍历序列构造二叉树|build_tree
根据前序和后序遍历构造二叉树|construct_from_pre_post
最大二叉树|construct_maximum_binary_tree
完全二叉树的节点个数|count_nodes

Hard

二叉树后序遍历|postorder_traversal

DynamicPrograming

动态规划

Rust 解动态规划题思路

主要思路与其他语言类似。还是通过寻找状态转移方程(递推关系),通常要使用 vec 来保存之前的结果来提升性能。 常用到的空间优化方式有滚动数组,来将二维数组压成一维或减少数组空间大小。大部分情况都是背包问题(01背包,完全背包,多重背包)问题的变种。 学习资料: liweiwei leetcode 经典动规解析

Easy

简单难度的动态规划题

爬楼梯|climb_stairs
三步问题|ways_to_step
连续数列|max_sub_array
按摩师|massage
打家劫舍|rob
使用最小花费爬楼梯|min_cost_climbing_stairs
买卖股票的最佳时机|max_profit
最长连续递增序列|find_length_of_lcis
区域和检索 - 数组不可变|NumArray
有序数组的平方|sorted_squares
509 斐波那契数

Medium

中等难度的动态规划题

最长上升子序列|length_of_lis
最长递增子序列的个数|find_number_of_lis
最小路径和|min_path_sum
最长回文子串|longest_palindrome
打家劫舍 II|robs
打家劫舍 III|robs
不同路径 II|unique_paths_with_obstacles
二维区域和检索 - 矩阵不可变|NumMatrix
完全平方数|num_squares
55跳跃游戏
45跳跃游戏||
413等差数列划分
221最大正方形

HOT100 🔥

Hot100类型题

Easy

简单难度的HOT100题

柠檬水找零|lemonade_change
找到所有数组中消失的数字|find_disappeared_numbers
最短无序连续子数组|find_unsorted_subarray
字符串相加|add_strings
二分查找|binary_search
第一个错误的版本|first_bad_version

Medium

中等难度的HOT100题

除自身以外数组的乘积|product_except_self
分割等和子集|can_partition
全排列|permute
括号生成|generate_parenthesis
子集|subsets
零钱兑换|coin_change
不同路径|unique_paths
单词搜索|exist
单词拆分|word_break
无重复字符的最长子串|length_of_longest_substring
课程表|can_finish
在排序数组中查找元素的第一个和最后一个位置|search_range

Hard

困难难度的Hot100题目

接雨水|trap

Others

其他分类的题目集合

Easy

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面|exchange
用栈实现队列|MyQueue
用队列实现栈|MyStack
最小栈|MinStack
用栈操作构建数组|build_array
判断子序列|is_subsequence
821 字符的最短距离
997 找到小镇的法官
118 杨辉三角

Medium

807 保持城市天际线
11 盛最多水的容器 475 供暖器

Hard

缺失的第一个正数|first_missing_positive

周赛

记录周赛题目

2020.8.9 双周赛

第 k 个缺失的正整数|find_kth_positive
K 次操作转变字符串|can_convert_string

You might also like...
Rust Persistent Data Structures

Rust Persistent Data Structures Rust Persistent Data Structures provides fully persistent data structures with structural sharing. Setup To use rpds a

Rust crate to extend io::Read & io::Write types with progress callbacks

progress-streams Rust crate to provide progress callbacks for types which implement io::Read or io::Write. Examples Reader extern crate progress_strea

Parameterized routing for generic resources in Rust

Usher Usher provides an easy way to construct parameterized routing trees in Rust. The nodes of these trees is naturally generic, allowing Usher to le

RiteLinked - LinkedHashMap & LinkedHashSet in Rust

RiteLinked -- HashMap-like containers that hold their key-value pairs in a user controllable order RiteLinked provides more up to date versions of Lin

A proof of concept implementation of cyclic data structures in stable, safe, Rust.

A proof of concept implementation of cyclic data structures in stable, safe, Rust. This demonstrates the combined power of the static-rc crate and the

Doubly-Linked List Implementation in Rust

Doubly-Linked List Implementation in Rust Purely for educational and recreational purposes. For real world production please use std::collections::Lin

Rust library for string parsing of basic data structures.

afmt Simple rust library for parsing basic data structures from strings. Usage You can specify string formats to any strucute, via the use of the fmt

Hash Table Implementation in Rust
Hash Table Implementation in Rust

Hash Table Implementation in Rust Purely for educational and recreational purposes. For real world production please use std::collections::HashMap. Fo

SegVec data structure for rust. Similar to Vec, but allocates memory in chunks of increasing size.

segvec This crate provides the SegVec data structure. It is similar to Vec, but allocates memory in chunks of increasing size, referred to as "segment

Owner
yuuang
FE Node.js Rust umi SSR FaaS @OSSDAO-ORG•AIRDROP-0x8bae7dC5C120DFe5804031b700061711309576d2
yuuang
my leetcode solutions in rust

My Leetcode Solution in Rust Run cargo run {id} to initialize the template submission file of "question #id". Run cargo test test_{id} to test the sol

Aylei 598 Jan 1, 2023
A full-featured Leetcode API on Rust language

LeetCode API Rust Library This Rust library provides a convenient way to interact with the LeetCode API, allowing you to programmatically access LeetC

null 2 Jul 13, 2023
The solutions for Leetcode's problem

Leetcode The solutions for Leetcode's problem # Ttitle Solution Diffculty 1 Two Sum Rust, TypeScript Easy 5 Longest Palindromic Substring Rust, TypeSc

Eleven 2 Jul 21, 2022
Rust-algorithm-club - Learn algorithms and data structures with Rust

Rust Algorithm Club ?? ?? This repo is under construction. Most materials are written in Chinese. Check it out here if you are able to read Chinese. W

Weihang Lo 360 Dec 28, 2022
Ternary search tree collection in rust

tst Ternary search tree collection in rust with similar API to std::collections as it possible. Ternary search tree is a type of trie (sometimes calle

Alexey Pervushin 20 Dec 7, 2022
Array helpers for Rust's Vector and String types

array_tool Array helpers for Rust. Some of the most common methods you would use on Arrays made available on Vectors. Polymorphic implementations for

Daniel P. Clark 69 Dec 9, 2022
Generic array types in Rust

generic-array This crate implements generic array types for Rust. Requires minumum Rust version of 1.36.0, or 1.41.0 for From<[T; N]> implementations

Bartłomiej Kamiński 325 Dec 25, 2022
A priority queue for Rust with efficient change function.

PriorityQueue This crate implements a Priority Queue with a function to change the priority of an object. Priority and items are stored in an IndexMap

null 139 Dec 30, 2022
K-dimensional tree in Rust for fast geospatial indexing and lookup

kdtree K-dimensional tree in Rust for fast geospatial indexing and nearest neighbors lookup Crate Documentation Usage Benchmark License Usage Add kdtr

Rui Hu 152 Jan 2, 2023
Roaring bitmap implementation for Rust

RoaringBitmap This is not yet production ready. The API should be mostly complete now. This is a Rust port of the Roaring bitmap data structure, initi

Roaring bitmaps: A better compressed bitset 552 Jan 1, 2023