• Stars
    star
    361
  • Rank 117,957 (Top 3 %)
  • Language
    Rust
  • Created about 5 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

solve questions in leetcode by Rust

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 供暖器
390 消除游戏
334 递增的三元子序列
373 查找和最小的K对数字

Hard

缺失的第一个正数|first_missing_positive

周赛

记录周赛题目

2020.8.9 双周赛

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

More Repositories

1

ssr

A most advanced ssr framework support React17/React18/Vue2/Vue3 on Earth that implemented serverless-side render specification.
TypeScript
2,587
star
2

egg-react-ssr

最小而美的Egg + React + SSR 服务端渲染应用骨架,同时支持JS和TS
TypeScript
1,899
star
3

fe-dev-playbook

教你如何打造舒适、高效、时尚的前端开发环境
Vue
686
star
4

vite-design

下一代构建工具 vite 文档翻译 源码解析
Vue
315
star
5

v8-profiler-rs

Analyze V8 HeapSnapShot By Rust
Rust
178
star
6

node-ffi-rs

Implement ffi in Node.js by Rust and NAPI
Rust
88
star
7

douBanByVueSsr

基于最新的vue2.3的ssr的仿豆瓣程序,后端restful api采用node+express
JavaScript
55
star
8

dclone

The simplest command for downloading specified directory in github/gitlab can cutting down download time
TypeScript
42
star
9

webpackTpl

webpack + Vue 多页面应用脚手架模版
JavaScript
32
star
10

standardjs-vue

combine standardjs with .vue|js|ts files
JavaScript
25
star
11

create-ssr-app

Create Serverless SSR App
TypeScript
24
star
12

ScrollImage

原生js实现的图片滑动
Vue
13
star
13

myDouBanApi

基于node+express的豆瓣电影API
JavaScript
13
star
14

memoryshare

share memory between diffrent Node.js process
Rust
10
star
15

2020-NodeParty-PPT

9
star
16

vite-raw-plugin

JavaScript
8
star
17

nestjs-vue3-ssr-pinia

https://github.com/zhangyuang/ssr
TypeScript
7
star
18

micro-app-ssr

TypeScript
6
star
19

weChatProgram

仿豆瓣的微信小程序
JavaScript
5
star
20

color-thief-wasm

color-thief for webassembly by Rust
Rust
3
star
21

Canvas

canvas图片处理小应用
JavaScript
3
star
22

ScrollImageByVue

借助vue的transition标签实现的图片滑动效果
JavaScript
2
star
23

long.js-design

JavaScript
1
star
24

tplChange

php smarty to node nunjucks
JavaScript
1
star
25

vue-loader-ssr-bug

TypeScript
1
star
26

lerna-napi

Develop napi by rust, Manage and deploy crates by lerna
Rust
1
star
27

ykserver

JavaScript
1
star
28

reExtension

批量替换文件后缀名的工具 by nodejs
JavaScript
1
star
29

create-wasm-project

TypeScript
1
star
30

abstract-socket-rs

Implement abstract-socket based on ffi-rs without node-gyp
JavaScript
1
star