├── 基础四大件 ├── OS.md ├── 计网.md ├── 计组.md ├── 设计模式.md ├── readme.md ├── 算法.md └── 数据结构.md ├── linux使用 ├── RK3399.md └── docker.md ├── images ├── readme.md ├── 午.jpg ├── 早.jpg ├── 晚.jpg ├── 游泳.gif └── hard_job.jpg ├── slamNotes ├── use_ceres.md ├── image.png ├── images │ ├── 4_1.png │ ├── 5_1.png │ ├── 7-7.png │ ├── happy.gif │ ├── uestc1.png │ ├── uestc2.png │ └── readme.md ├── 2023.md ├── 2022.md ├── 激光SLAM │ ├── LVI-SAM学习笔记.md │ ├── LIO-SAM学习笔记.md │ └── readme.md ├── 2021.md ├── slam论文阅读 │ └── readme.md ├── 3dGauss_splatting │ └── readme.md ├── TUM_KITTI.md ├── use_g2o.md ├── slam开源方案 │ └── readme.md ├── SLAM面试问题整理.md ├── ros常用消息.md ├── 毕业设计.md └── readme.md ├── 牛客网刷题笔记 ├── 动态规划专项 │ ├── 二维dp.md │ ├── 差分.md │ ├── 树形dp.md │ ├── 区间dp.md │ ├── 前缀和.md │ ├── 数位dp.md │ ├── 状压dp.md │ └── 背包.md ├── 算法入门 │ ├── 搜索.md │ ├── 动态规划.md │ ├── 基础算法.md │ └── 数据结构.md ├── 智力题总结.md ├── 笔试总结.md ├── readme.md ├── 面试必刷TOP101 │ ├── 贪心算法.md │ ├── 哈希.md │ ├── 字符串.md │ ├── 模拟.md │ ├── 二分查找和排序.md │ ├── 双指针.md │ ├── 递归和回溯.md │ └── 堆栈队列.md ├── 输入输出练习.md └── 顺序刷题.md ├── python相关 ├── mmdetection.md └── readme.md ├── learnCpp ├── readme.md └── 面经.md └── readme.md /基础四大件/OS.md: -------------------------------------------------------------------------------- 1 | # 操作系统 2 | -------------------------------------------------------------------------------- /基础四大件/计网.md: -------------------------------------------------------------------------------- 1 | # 计算机网络 2 | -------------------------------------------------------------------------------- /基础四大件/计组.md: -------------------------------------------------------------------------------- 1 | # 计算机组成原理 2 | -------------------------------------------------------------------------------- /基础四大件/设计模式.md: -------------------------------------------------------------------------------- 1 | # 设计模式 2 | -------------------------------------------------------------------------------- /linux使用/RK3399.md: -------------------------------------------------------------------------------- 1 | # rk3399pro 2 | -------------------------------------------------------------------------------- /images/readme.md: -------------------------------------------------------------------------------- 1 | # some images 2 | -------------------------------------------------------------------------------- /slamNotes/use_ceres.md: -------------------------------------------------------------------------------- 1 | # How to use Ceres 2 | -------------------------------------------------------------------------------- /images/午.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/images/午.jpg -------------------------------------------------------------------------------- /images/早.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/images/早.jpg -------------------------------------------------------------------------------- /images/晚.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/images/晚.jpg -------------------------------------------------------------------------------- /images/游泳.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/images/游泳.gif -------------------------------------------------------------------------------- /images/hard_job.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/images/hard_job.jpg -------------------------------------------------------------------------------- /slamNotes/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/image.png -------------------------------------------------------------------------------- /slamNotes/images/4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/images/4_1.png -------------------------------------------------------------------------------- /slamNotes/images/5_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/images/5_1.png -------------------------------------------------------------------------------- /slamNotes/images/7-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/images/7-7.png -------------------------------------------------------------------------------- /slamNotes/images/happy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/images/happy.gif -------------------------------------------------------------------------------- /slamNotes/images/uestc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/images/uestc1.png -------------------------------------------------------------------------------- /slamNotes/images/uestc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuqian62/notebook/HEAD/slamNotes/images/uestc2.png -------------------------------------------------------------------------------- /slamNotes/2023.md: -------------------------------------------------------------------------------- 1 | # My work on slam in 2023 2 | ## project1 3 | * 主要工作 4 | * 项目难点 5 | 6 | ## project2 7 | * 主要工作 8 | * 项目难点 9 | -------------------------------------------------------------------------------- /slamNotes/2022.md: -------------------------------------------------------------------------------- 1 | # My work on slam in 2022 2 | ## MSCKF改进特征跟踪 3 | * 主要工作 4 | * 项目难点 5 | ## OpenVINS改进特征跟踪 6 | * 主要工作 7 | * 项目难点 8 | -------------------------------------------------------------------------------- /slamNotes/激光SLAM/LVI-SAM学习笔记.md: -------------------------------------------------------------------------------- 1 | # LVI-SAM学习笔记 2 | * [代码地址](https://github.com/TixiaoShan/LVI-SAM) 3 | * [注释版代码](https://github.com/kvlton/LVI-SAM) 4 | -------------------------------------------------------------------------------- /slamNotes/2021.md: -------------------------------------------------------------------------------- 1 | # My work on slam in 2021 2 | ## MSCKF加回环检测 3 | * 主要工作 4 | * 项目难点 5 | ## MSCKF双目改单目 6 | * 主要工作 7 | * 项目难点 8 | ## LARVIO加回环检测 9 | * 主要工作 10 | * 项目难点 11 | -------------------------------------------------------------------------------- /slamNotes/slam论文阅读/readme.md: -------------------------------------------------------------------------------- 1 | # slam论文 2 | 3 | 1. a 4 | ` 5 | Macario Barros A, Michel M, Moline Y, et al. A comprehensive survey of visual slam algorithms[J]. Robotics, 2022, 11(1): 24.` 6 | 7 | 3. b 8 | 9 | 10 | 5. c 11 | 12 | -------------------------------------------------------------------------------- /slamNotes/激光SLAM/LIO-SAM学习笔记.md: -------------------------------------------------------------------------------- 1 | # LIO-SAM学习笔记 2 | 3 | * [代码地址](https://github.com/TixiaoShan/LIO-SAM) 4 | * [注释版代码](https://github.com/smilefacehh/LIO-SAM-DetailedNote) 5 | * [数据集](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq) 6 | * [联合标定工具](https://github.com/ethz-asl/lidar_align) 7 | -------------------------------------------------------------------------------- /slamNotes/images/readme.md: -------------------------------------------------------------------------------- 1 | # images 2 | 3 | `4_1.png` 4 | 5 | ![4_1](4_1.png) 6 | 7 | `5_1.png` 8 | 9 | ![5_1](5_1.png) 10 | 11 | `7-7.png` 12 | 13 | ![7_7](7-7.png) 14 | 15 | `happy.gif` 16 | 17 | ![happy](happy.gif) 18 | 19 | 20 | `uestc1.png` 21 | 22 | ![uestc1](uestc1.png) 23 | 24 | `uestc2.png` 25 | 26 | ![uestc2](uestc2.png) 27 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/二维dp.md: -------------------------------------------------------------------------------- 1 | # 二维dp 2 | 3 | ## 目录 4 | 5 | - [DP39](#DP39) 6 | - [DP40](#DP40) 7 | 8 | ### DP39 9 | * DP1 dosomething 10 | 11 | 描述 12 | ``` 13 | 14 | ``` 15 | 16 | ```cpp 17 | 18 | ``` 19 | 20 |
21 | ↥ Back To Top 22 |
23 | 24 | 25 | ### DP40 26 | * DP1 dosomething 27 | 28 | 描述 29 | ``` 30 | 31 | ``` 32 | 33 | ```cpp 34 | 35 | ``` 36 | 37 |
38 | ↥ Back To Top 39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/差分.md: -------------------------------------------------------------------------------- 1 | # 差分 2 | 3 | ## 目录 4 | 5 | - [DP37](#DP37) 6 | - [DP38](#DP38) 7 | 8 | 9 | 10 | ### DP37 11 | * DP1 dosomething 12 | 13 | 描述 14 | ``` 15 | 16 | ``` 17 | 18 | ```cpp 19 | 20 | ``` 21 | 22 |
23 | ↥ Back To Top 24 |
25 | 26 | 27 | ### DP38 28 | * DP1 dosomething 29 | 30 | 描述 31 | ``` 32 | 33 | ``` 34 | 35 | ```cpp 36 | 37 | ``` 38 | 39 |
40 | ↥ Back To Top 41 |
42 | 43 | -------------------------------------------------------------------------------- /基础四大件/readme.md: -------------------------------------------------------------------------------- 1 | * [思维导图](https://drive.google.com/drive/folders/1pvM8CPCwbjh-aycWJhaDgsiNUOzeivO3?usp=sharing) 2 | 3 | # 数据结构和算法 4 | * [数据结构](./数据结构.md) 5 | * [算法](./算法.md) 6 | # 计算机组成原理 7 | * [计组](./计组.md) 8 | # 计算机操作系统 9 | * [OS](./OS.md) 10 | * [操作系统总结](https://www.cnblogs.com/cxuanBlog/p/13297199.html) 11 | # 计算机网络 12 | * [计网](计网.md) 13 | * [笔记](https://blog.csdn.net/weixin_45067603/article/details/106974036) 14 | * [思维导图](https://www.edrawsoft.cn/viewer/public/s/17118661591967) 15 | * 16 | --- 17 | --- 18 | --- 19 | # 设计模式 20 | * [设计模式](./设计模式.md) 21 | 22 | 23 | # 数据库 24 | * [mysql](./mysql.md) 25 | -------------------------------------------------------------------------------- /牛客网刷题笔记/算法入门/搜索.md: -------------------------------------------------------------------------------- 1 | # 搜索 2 | 3 | ## 目录 4 | 5 | 6 | - [bfs](#bfs) 7 | - [AB19](#AB19) 8 | - [AB20](#AB20) 9 | 10 | 11 | - [dfs](#dfs) 12 | - [AB21](#AB21) 13 | - [AB22](#AB22) 14 | - [AB23](#AB23) 15 | 16 | 17 | ## bfs 18 | ### AB1 19 | * AB1 dosomething 20 | 21 | 描述 22 | ``` 23 | 24 | ``` 25 | 26 | ```cpp 27 | 28 | ``` 29 | 30 |
31 | ↥ Back To Top 32 |
33 | 34 | 35 | ## dfs 36 | ### AB1 37 | * AB1 dosomething 38 | 39 | 描述 40 | ``` 41 | 42 | ``` 43 | 44 | ```cpp 45 | 46 | ``` 47 | 48 |
49 | ↥ Back To Top 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /牛客网刷题笔记/算法入门/动态规划.md: -------------------------------------------------------------------------------- 1 | # 动态规划 2 | 3 | ## 目录 4 | 5 | 6 | - [线性dp](#线性dp) 7 | - [AB34](#AB34) 8 | - [AB35](#AB35) 9 | - [AB36](#AB36) 10 | - [AB37](#AB37) 11 | - [AB38](#AB38) 12 | 13 | 14 | - [背包](#背包) 15 | - [AB39](#AB39) 16 | - [AB40](#AB40) 17 | - [AB41](#AB41) 18 | 19 | 20 | ## 线性dp 21 | 22 | ### AB1 23 | * AB1 dosomething 24 | 25 | 描述 26 | ``` 27 | 28 | ``` 29 | 30 | ```cpp 31 | 32 | ``` 33 | 34 |
35 | ↥ Back To Top 36 |
37 | 38 | 39 | ## 背包 40 | 41 | ### AB1 42 | * AB1 dosomething 43 | 44 | 描述 45 | ``` 46 | 47 | ``` 48 | 49 | ```cpp 50 | 51 | ``` 52 | 53 |
54 | ↥ Back To Top 55 |
56 | 57 | 58 | -------------------------------------------------------------------------------- /牛客网刷题笔记/智力题总结.md: -------------------------------------------------------------------------------- 1 | # 智力题总结 2 | 3 | * [博客总结29道](https://blog.csdn.net/xiao__oaix/article/details/78144904?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165778013916782388028883%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165778013916782388028883&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-78144904-null-null.142^v32^new_blog_pos_by_title,185^v2^control&utm_term=%E6%99%BA%E5%8A%9B%E9%A2%98%E6%80%BB%E7%BB%93&spm=1018.2226.3001.4187) 4 | * [200+题和解答](https://blog.csdn.net/hilyoo/article/details/4445858) 5 | 6 | 1. 100层楼,只有2个鸡蛋,想要判断出那一层刚好让鸡蛋碎掉,给出策略(滴滴笔试中两个铁球跟这个是一类题) 7 | 2. 毒药问题,n拼毒药,要快速找出哪一瓶有毒,需要几只小白鼠 8 | 3. 博弈论问题 9 | 4. 先手必胜策略问题:n本书,每次能够拿X-X本,怎么拿必胜 10 | 5. 放n只蚂蚁在一条树枝上,蚂蚁与蚂蚁之间碰到就各自往反方向走,问总距离或者时间。 11 | 6. 瓶子换饮料问题:多少个瓶子能够换1瓶饮料,问最多能喝几瓶 12 | -------------------------------------------------------------------------------- /slamNotes/3dGauss_splatting/readme.md: -------------------------------------------------------------------------------- 1 | # 3d Gauss splatting 2 | ## 论文和代码 3 | * [Gaussian Splatting](https://github.com/graphdeco-inria/gaussian-splatting) 4 | * [3D-Gaussian-Splatting-Papers](https://github.com/Awesome3DGS/3D-Gaussian-Splatting-Papers) 5 | 6 | ## 教程 7 | * [A beginner friendly introduction](https://www.reshot.ai/3d-gaussian-splatting) 8 | * [3D Gaussian Splatting入门指南](https://www.bilibili.com/read/cv26465887/) 9 | * [3D Gaussian Splatting for Real-Time Radiance Field Rendering论文中代码复现及排错过程](https://blog.csdn.net/Destiny_Di/article/details/134237863?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171210995316800197024678%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171210995316800197024678&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-134237863-null-null.142^v100^pc_search_result_base5&utm_term=3D%20Gaussian%20Splatting%20for%20Real-Time%20Radiance%20Field%20Rendering&spm=1018.2226.3001.4449) 10 | 11 | ## 应用案例 12 | * [其域LCC](https://www.xgrids.cn/lcc) 13 | 14 | 15 | -------------------------------------------------------------------------------- /牛客网刷题笔记/笔试总结.md: -------------------------------------------------------------------------------- 1 | # 字节 2 | 3 | ```cpp 4 | void dfs(vector>& arr,vector>&vistied,int x,int y,int& res){ 5 | res++; 6 | int len_x=arr.size(); 7 | int len_y=arr[0].size(); 8 | vistied[x][y]=1; 9 | if(x-1>=0&&!vistied[x-1][y]&&(arr[x-1][y]=='D'||arr[x-1][y]=='.')) dfs(arr,vistied,x-1,y,res); 10 | if(x+1=0&&!vistied[x][y-1]&&(arr[x][y-1]=='R'||arr[x][y-1]=='.')) dfs(arr,vistied,x,y-1,res); 12 | if(y+1>n>>m; 17 | vector> mapp(n,vector(m)); 18 | int x,y; 19 | for(int i=0;i>aa; 22 | for(int j=0;j> visited(n,vector(m,0)); 31 | int res=0; 32 | dfs(mapp,visited,x,y,res); 33 | cout< 39 |
40 | ↥ Back To Top 41 |
42 | 43 | # LOAM 44 | * [代码链接](https://github.com/HKUST-Aerial-Robotics/A-LOAM) 45 | 46 | 47 |
48 | ↥ Back To Top 49 |
50 | 51 | # Lego-LOAM 52 | * [代码链接](https://github.com/RobustFieldAutonomyLab/LeGO-LOAM) 53 | 54 | 55 |
56 | ↥ Back To Top 57 |
58 | 59 | # livox-LOAM 60 | * [代码链接](https://github.com/hku-mars/loam_livox) 61 | 62 | 63 |
64 | ↥ Back To Top 65 |
66 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/树形dp.md: -------------------------------------------------------------------------------- 1 | # 树形dp 2 | 3 | ## 目录 4 | 5 | - [DP54](#DP54) 6 | - [DP55](#DP55) 7 | - [DP56](#DP56) 8 | - [DP57](#DP57) 9 | - [DP58](#DP58) 10 | 11 | 12 | ### DP54 13 | * DP54 小红的树 14 | 15 | 描述 16 | ``` 17 | 小红拿到了一棵有根树。根节点为1号节点。 18 | 所谓树,指没有回路的无向连通图。 19 | 现在小红想给一部分点染成红色。之后她有 q次询问,每次询问某点的子树红色节点的个数。 20 | 输入描述: 21 | 第一行一个正整数 n,代表树的节点个数。 22 | 第二行有 n-1个正整数,分别表示第 2个节点到第 n个节点每个节点的父亲。 23 | 接下来一个长度为 n的、由'W'或'R'字符组成的字符串。第 i个字符为'W'代表该字符没被染色,若字符为'R'代表该字符被染成了红色。 24 | 接下来一个正整数 q,代表小红的询问次数。 25 | 接下来的 q行,每行有一个正整数x,代表一次询问。 26 | (1≤n,q≤10^5,1≤x≤n) 27 | 输出描述: 28 | 对于每次询问,输出一个整数,代表节点xx的子树的红色节点个数。 29 | ``` 30 | 31 | ```cpp 32 | 33 | ``` 34 | 35 |
36 | ↥ Back To Top 37 |
38 | 39 | 40 | ### DP55 41 | * DP1 dosomething 42 | 43 | 描述 44 | ``` 45 | 46 | ``` 47 | 48 | ```cpp 49 | 50 | ``` 51 | 52 |
53 | ↥ Back To Top 54 |
55 | 56 | 57 | ### DP56 58 | * DP1 dosomething 59 | 60 | 描述 61 | ``` 62 | 63 | ``` 64 | 65 | ```cpp 66 | 67 | ``` 68 | 69 |
70 | ↥ Back To Top 71 |
72 | 73 | 74 | ### DP57 75 | * DP1 dosomething 76 | 77 | 描述 78 | ``` 79 | 80 | ``` 81 | 82 | ```cpp 83 | 84 | ``` 85 | 86 |
87 | ↥ Back To Top 88 |
89 | 90 | 91 | ### DP58 92 | * DP1 dosomething 93 | 94 | 描述 95 | ``` 96 | 97 | ``` 98 | 99 | ```cpp 100 | 101 | ``` 102 | 103 |
104 | ↥ Back To Top 105 |
106 | 107 | -------------------------------------------------------------------------------- /python相关/readme.md: -------------------------------------------------------------------------------- 1 | # python 相关笔记 2 | 3 | [python基础](https://www.runoob.com/python3/python3-tutorial.html) 4 | [python100天](https://www.bookstack.cn/read/Python-100-Days/README.md) 5 | 6 | ## 虚拟环境配置 7 | ```bash 8 | conda create -n rich python=3.7 #创建环境 9 | conda activate rich #激活环境 10 | conda deactivate rich #退出环境 11 | conda remove -n rich --all #删除环境 12 | ``` 13 | ## requirements 14 | ``` 15 | pip install -r requirements.txt 16 | ``` 17 | 例如 18 | ``` 19 | pytest==6.2.5 20 | pytest-json-report==1.4.1 21 | pytest-metadata==1.11.0 22 | pytest-ordering==0.6 23 | PyTestReport==0.2.1 24 | python-dateutil==2.8.2 25 | ``` 26 | * [解决安装缓慢的问题](https://blog.csdn.net/weixin_42455006/article/details/121957633?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164964070016780271982907%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164964070016780271982907&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-121957633.142^v7^article_score_rank,157^v4^control&utm_term=%E5%AE%89%E8%A3%85requirements.txt%E5%A4%AA%E6%85%A2&spm=1018.2226.3001.4187) 27 | 28 | ```bash 29 | pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.douban.com 30 | ``` 31 | 32 | * [python图形界面示例](https://github.com/liuqian62/loopmark) 33 | # [mmdetetion](https://github.com/liuqian62/notebook/blob/main/python%E7%9B%B8%E5%85%B3/mmdetection.md) 34 | # OpenCV教程 35 | * [OpenCV中文官方文档](https://woshicver.com/) 36 | * [OpenCV 4.0 中文文档](https://opencv.apachecn.org/#/) 37 | 38 | # pyechart 39 | * [pyechart中文文档](https://gallery.pyecharts.org/#/README) 40 | * [pyechart的github地址](https://github.com/pyecharts/pyecharts) 41 | * [pyechart图库](https://github.com/pyecharts/pyecharts-gallery) 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/区间dp.md: -------------------------------------------------------------------------------- 1 | # 区间dp 2 | 3 | ## 目录 4 | 5 | - [DP47](#DP47) 6 | - [DP48](#DP48) 7 | - [DP49](#DP49) 8 | - [DP50](#DP50) 9 | - [DP51](#DP51) 10 | - [DP52](#DP52) 11 | - [DP53](#DP53) 12 | 13 | 14 | ### DP47 15 | * DP1 dosomething 16 | 17 | 描述 18 | ``` 19 | 20 | ``` 21 | 22 | ```cpp 23 | 24 | ``` 25 | 26 |
27 | ↥ Back To Top 28 |
29 | 30 | 31 | ### DP48 32 | * DP1 dosomething 33 | 34 | 描述 35 | ``` 36 | 37 | ``` 38 | 39 | ```cpp 40 | 41 | ``` 42 | 43 |
44 | ↥ Back To Top 45 |
46 | 47 | 48 | ### DP49 49 | * DP1 dosomething 50 | 51 | 描述 52 | ``` 53 | 54 | ``` 55 | 56 | ```cpp 57 | 58 | ``` 59 | 60 |
61 | ↥ Back To Top 62 |
63 | 64 | 65 | ### DP50 66 | * DP1 dosomething 67 | 68 | 描述 69 | ``` 70 | 71 | ``` 72 | 73 | ```cpp 74 | 75 | ``` 76 | 77 |
78 | ↥ Back To Top 79 |
80 | 81 | 82 | ### DP51 83 | * DP1 dosomething 84 | 85 | 描述 86 | ``` 87 | 88 | ``` 89 | 90 | ```cpp 91 | 92 | ``` 93 | 94 |
95 | ↥ Back To Top 96 |
97 | 98 | 99 | ### DP52 100 | * DP1 dosomething 101 | 102 | 描述 103 | ``` 104 | 105 | ``` 106 | 107 | ```cpp 108 | 109 | ``` 110 | 111 |
112 | ↥ Back To Top 113 |
114 | 115 | 116 | ### DP53 117 | * DP1 dosomething 118 | 119 | 描述 120 | ``` 121 | 122 | ``` 123 | 124 | ```cpp 125 | 126 | ``` 127 | 128 |
129 | ↥ Back To Top 130 |
131 | 132 | -------------------------------------------------------------------------------- /基础四大件/算法.md: -------------------------------------------------------------------------------- 1 | # 算法 2 | ## 目录 3 | - [查找](#查找) 4 | - [查找的基本概念](#查找的基本概念) 5 | - [线性表的查找](#线性表的查找) 6 | - [树表的查找](#树表的查找) 7 | - [散列表的查找](#散列表的查找) 8 | 9 | --- 10 | 11 | - [排序](#排序) 12 | - [排序的基本概念](#排序的基本概念) 13 | - [插入排序](#插入排序) 14 | - [交换排序](#交换排序) 15 | - [旋转排序](#旋转排序) 16 | - [归并排序](#归并排序) 17 | - [基数排序](#基数排序) 18 | - [外部排序](#外部排序) 19 | - [排序方法比较](#排序方法比较) 20 | 21 | # 查找 22 | 23 |
24 | ↥ Back To Top 25 |
26 | 27 | 28 | # 查找的基本概念 29 | 30 |
31 | ↥ Back To Top 32 |
33 | 34 | 35 | # 线性表的查找 36 | 37 |
38 | ↥ Back To Top 39 |
40 | 41 | 42 | # 树表的查找 43 | 44 |
45 | ↥ Back To Top 46 |
47 | 48 | 49 | # 散列表的查找 50 | 51 |
52 | ↥ Back To Top 53 |
54 | 55 | 56 | 57 | --- 58 | 59 | # 排序 60 | 61 |
62 | ↥ Back To Top 63 |
64 | 65 | 66 | # 排序的基本概念 67 | 68 |
69 | ↥ Back To Top 70 |
71 | 72 | 73 | # 插入排序 74 | 75 |
76 | ↥ Back To Top 77 |
78 | 79 | 80 | # 交换排序 81 | 82 |
83 | ↥ Back To Top 84 |
85 | 86 | 87 | # 旋转排序 88 | 89 |
90 | ↥ Back To Top 91 |
92 | 93 | 94 | # 归并排序 95 | 96 |
97 | ↥ Back To Top 98 |
99 | 100 | 101 | # 基数排序 102 | 103 |
104 | ↥ Back To Top 105 |
106 | 107 | 108 | # 外部排序 109 | 110 |
111 | ↥ Back To Top 112 |
113 | 114 | 115 | # 排序方法比较 116 | 117 |
118 | ↥ Back To Top 119 |
120 | 121 | -------------------------------------------------------------------------------- /slamNotes/TUM_KITTI.md: -------------------------------------------------------------------------------- 1 | # 保存为TUM和KITTI格式的位姿 2 | ```cpp 3 | void SaveKittiFormat(const string& map_path) 4 | { 5 | FILE *fp = NULL; 6 | char end1 = 0x0d; // "/n" 7 | char end2 = 0x0a; 8 | 9 | // lidar odometry 10 | string lidar_tum_file = map_path + "imu_data_res_kitti.txt"; 11 | fp = fopen(lidar_tum_file.c_str(), "w+"); 12 | 13 | if (fp == NULL) 14 | { 15 | printf("fail to open file %s ! \n", lidar_tum_file.c_str()); 16 | exit(1); 17 | } 18 | else 19 | printf("KITTI : write lidar data to %s \n", lidar_tum_file.c_str()); 20 | 21 | for (int i = 0; i < imu_data_.size(); ++i) 22 | { 23 | auto q = imu_data_[i].continous_quat; 24 | Eigen::Matrix3d R; 25 | R = q; 26 | 27 | Eigen::Vector3d t = imu_data_[i].pos; 28 | double time = imu_data_[i].stamp; 29 | fprintf(fp, "%.5lf %.5lf %.5lf %.5lf %.5lf %.5lf %.5lf %.5lf %.5lf %.5lf %.5lf %.5lf%c", 30 | R(0,0),R(0,1),R(0,2),t.x(), 31 | R(1,0),R(1,1),R(1,2),t.y(), 32 | R(2,0),R(2,1),R(2,2),t.z(), 33 | end2); 34 | } 35 | fclose(fp); 36 | } 37 | 38 | void SaveTumFormat(const string& map_path) 39 | { 40 | FILE *fp = NULL; 41 | char end1 = 0x0d; // "/n" 42 | char end2 = 0x0a; 43 | 44 | // lidar odometry 45 | string lidar_tum_file = map_path + "imu_data_res.txt"; 46 | fp = fopen(lidar_tum_file.c_str(), "w+"); 47 | 48 | if (fp == NULL) 49 | { 50 | printf("fail to open file %s ! \n", lidar_tum_file.c_str()); 51 | exit(1); 52 | } 53 | else 54 | printf("TUM : write lidar data to %s \n", lidar_tum_file.c_str()); 55 | 56 | for (size_t i = 0; i < imu_data_.size(); ++i) 57 | { 58 | Eigen::Quaterniond q = imu_data_[i].continous_quat; 59 | Eigen::Vector3d t = imu_data_[i].pos; 60 | double time = imu_data_[i].stamp; 61 | fprintf(fp, "%.3lf %.3lf %.3lf %.3lf %.5lf %.5lf %.5lf %.5lf%c", 62 | time, t.x(), t.y(), t.z(), 63 | q.x(), q.y(), q.z(), q.w(), end2); 64 | } 65 | fclose(fp); 66 | } 67 | 68 | ``` 69 | -------------------------------------------------------------------------------- /牛客网刷题笔记/算法入门/基础算法.md: -------------------------------------------------------------------------------- 1 | # 基础算法 2 | 3 | ## 目录 4 | 5 | 6 | - [查找](#查找) 7 | - [AB24](#AB24) 8 | 9 | 10 | - [枚举](#枚举) 11 | - [A25](#AB25) 12 | 13 | 14 | - [递归](#递归) 15 | - [AB26](#AB26) 16 | - [AB27](#AB27) 17 | 18 | 19 | 20 | 21 | - [分治](#分治) 22 | - [AB28](#AB28) 23 | - [AB29](#AB29) 24 | 25 | 26 | 27 | - [排序](#排序) 28 | - [AB30](#AB30) 29 | 30 | 31 | - [贪心](#贪心) 32 | - [AB31](#AB31) 33 | - [AB32](#AB32) 34 | 35 | 36 | - [双指针](#双指针) 37 | - [AB33](#AB33) 38 | 39 | 40 | ## 查找 41 | 42 | ### AB1 43 | * AB1 dosomething 44 | 45 | 描述 46 | ``` 47 | 48 | ``` 49 | 50 | ```cpp 51 | 52 | ``` 53 | 54 |
55 | ↥ Back To Top 56 |
57 | 58 | 59 | ## 枚举 60 | 61 | ### AB1 62 | * AB1 dosomething 63 | 64 | 描述 65 | ``` 66 | 67 | ``` 68 | 69 | ```cpp 70 | 71 | ``` 72 | 73 |
74 | ↥ Back To Top 75 |
76 | 77 | 78 | ## 递归 79 | 80 | ### AB1 81 | * AB1 dosomething 82 | 83 | 描述 84 | ``` 85 | 86 | ``` 87 | 88 | ```cpp 89 | 90 | ``` 91 | 92 |
93 | ↥ Back To Top 94 |
95 | 96 | 97 | ## 分治 98 | 99 | 100 | ### AB1 101 | * AB1 dosomething 102 | 103 | 描述 104 | ``` 105 | 106 | ``` 107 | 108 | ```cpp 109 | 110 | ``` 111 | 112 |
113 | ↥ Back To Top 114 |
115 | 116 | 117 | ## 排序 118 | 119 | 120 | ### AB1 121 | * AB1 dosomething 122 | 123 | 描述 124 | ``` 125 | 126 | ``` 127 | 128 | ```cpp 129 | 130 | ``` 131 | 132 |
133 | ↥ Back To Top 134 |
135 | 136 | 137 | ## 贪心 138 | 139 | ### AB1 140 | * AB1 dosomething 141 | 142 | 描述 143 | ``` 144 | 145 | ``` 146 | 147 | ```cpp 148 | 149 | ``` 150 | 151 |
152 | ↥ Back To Top 153 |
154 | 155 | 156 | 157 | ## 双指针 158 | 159 | ### AB1 160 | * AB1 dosomething 161 | 162 | 描述 163 | ``` 164 | 165 | ``` 166 | 167 | ```cpp 168 | 169 | ``` 170 | 171 |
172 | ↥ Back To Top 173 |
174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /slamNotes/use_g2o.md: -------------------------------------------------------------------------------- 1 | # How to use g2o 2 | # 如何使用g2o(General Graphic Optimization) 3 | - [参考链接](https://mp.weixin.qq.com/s/j9h9lT14jCu-VvEPHQhtBw) 4 | - [参考链接](https://www.cnblogs.com/CV-life/p/10449028.html) 5 | - [参考链接](https://www.cnblogs.com/CV-life/archive/2019/03/13/10525579.html) 6 | ![img1](./image.png) 7 | * 图的核心 8 | 9 | 10 | * 顶点和边 11 | * 配置SparseOptimizer的优化算法和求解器 12 | * 如何求解 13 | 14 | ## 分步骤实现 15 | 16 | ```cpp 17 | typedef g2o::BlockSolver< g2o::BlockSolverTraits<3,1> > Block; // 每个误差项优化变量维度为3,误差值维度为1 18 | 19 | // 第1步:创建一个线性求解器LinearSolver 20 | Block::LinearSolverType* linearSolver = new g2o::LinearSolverDense(); 21 | 22 | // 第2步:创建BlockSolver。并用上面定义的线性求解器初始化 23 | Block* solver_ptr = new Block( linearSolver ); 24 | 25 | // 第3步:创建总求解器solver。并从GN, LM, DogLeg 中选一个,再用上述块求解器BlockSolver初始化 26 | g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg( solver_ptr ); 27 | 28 | // 第4步:创建终极大boss 稀疏优化器(SparseOptimizer) 29 | g2o::SparseOptimizer optimizer; // 图模型 30 | optimizer.setAlgorithm( solver ); // 设置求解器 31 | optimizer.setVerbose( true ); // 打开调试输出 32 | 33 | // 第5步:定义图的顶点和边。并添加到SparseOptimizer中 34 | CurveFittingVertex* v = new CurveFittingVertex(); //往图中增加顶点 35 | v->setEstimate( Eigen::Vector3d(0,0,0) ); 36 | v->setId(0); 37 | optimizer.addVertex( v ); 38 | for ( int i=0; isetId(i); 42 | edge->setVertex( 0, v ); // 设置连接的顶点 43 | edge->setMeasurement( y_data[i] ); // 观测数值 44 | edge->setInformation( Eigen::Matrix::Identity()*1/(w_sigma*w_sigma) ); // 信息矩阵:协方差矩阵之逆 45 | optimizer.addEdge( edge ); 46 | } 47 | 48 | // 第6步:设置优化参数,开始执行优化 49 | optimizer.initializeOptimization(); 50 | optimizer.optimize(100); 51 | ``` 52 | 53 | ## 创建一个线性求解器LinearSolver 54 | ## 创建BlockSovler。并用上面的定义的线性求解器初始化 55 | ## 创建总和求解器solver。并从GN, LM, DogLeg 中选一个,再用上述块求解器BlockSolver初始化 56 | ## 创建终极大boss 稀疏优化器(SparseOptimizer),并用已定义求解器作为求解方法 57 | ## 定义图的顶点和边。并添加到SparseOptimizer中 58 | 59 | ### 重写四个函数 60 | * virtual bool read(std::istream& is); 61 | * virtual bool write(std::ostream& os) const; 62 | * virtual void oplusImpl(const number_t* update); 63 | 64 | 顶点更新函数。非常重要的一个函数,主要用于优化过程中增量△x 的计算。我们根据增量方程计算出增量之后,就是通过这个函数对估计值进行调整的,因此这个函数的内容一定要重视。 65 | * virtual void setToOriginImpl(); 66 | 67 | 顶点重置函数,设定被优化变量的原始值。 68 | ## 设置优化参数,开始执行优化 69 | -------------------------------------------------------------------------------- /slamNotes/slam开源方案/readme.md: -------------------------------------------------------------------------------- 1 | # slam 开源方案总结和对比 2 | 3 |
4 | 5 | | 开源方案 | 传感器类型 | 测试数据集 | 精度 | 6 | | :---: | :---: | :---: | :---: | 7 | |[vins-Mono](https://github.com/HKUST-Aerial-Robotics/VINS-Mono)|mono+IMU| EuRoC| | 8 | |[Vins-Fusion]()|stereo/stereo+IMU/mono+IMU| EuRoC| | 9 | |[ORB_SLAM](https://github.com/raulmur/ORB_SLAM)|75.05| ?| | 10 | |[ORB_SLAM2](https://github.com/raulmur/ORB_SLAM2)|74.70| ?| | 11 | |[ORB_SLAM3](https://github.com/UZ-SLAMLab/ORB_SLAM3)|74.70| ?| | 12 | 13 | 14 |
15 | 16 | ## 区别 17 | * ORB_SLAM:`只针对的是单目SLAM系统` 18 | * ORB_SLAM2:`可以用于单目、双目、RGB_D相机。(并且作者公开的源码中包含ROS版本,可以实时跑自己的数据)` 19 | * ORB_SLAM3:`在2的基础上,还可以用于鱼眼相机;增加了视觉+imu的系统(VIO)。` 20 | 21 | ## 详情 22 | * ORB_SLAM:`ORB_SLAM:a Versatile and Accurate Monocular SLAM System 23 | (ORB_SLAM:一种通用精确的单目SLAM系统) 24 | 摘要:本文提出了一种基于特征的单目ORB-SLAM系统,该系统可在大小、室内和室外环境中实时运行。该系统对严重的运动杂波具有鲁棒性,允许宽基线的回环和重定位,并包括全自动初始化。基于近年来的优秀算法,我们从零开始设计了一个新的系统,它与所有SLAM系统使用了相同的功能:跟踪、建图、重定位和回环。采用优胜者汰的策略,选取特征点和用于重定位的关键帧 只有场景发生大的变化,这样增加了系统的鲁棒性,并形成一个紧凑和可跟踪的地图,系统允许长时间的运行。我们从最流行的数据集中选取27个序列进行评估。与其他最先进的单目SLAM系统相比,ORB_SLAM展现了最优的性能。(源码公开)` 25 | * ORB_SLAM2:`ORB_SLAM2:An Open-Source SLAM System for Monocular,Stereo,and RGB-D Cameras 26 | (ORB_SLAM2:一个用于单目、双目和RGB-D相机的开源SLAM系统) 27 | 摘要:我们提出ORB-SLAM2,一个完整的同时定位和地图构建(SLAM)系统,用于单目、双目和RGB-D相机,包括地图复用、回环和重定位功能。该系统在标准的中央处理单元上实时工作,适用于各种环境,从小型手持室内序列,到工业环境中的无人机飞行和在城市中行驶的汽车。我们的后端基于单目和双目观测的BA优化,允许使用公制尺度进行精确的轨迹估计。我们的系统包括一个轻量级的定位模式,利用视觉里程计跟踪未建图的区域,并与地图点匹配,允许零漂移定位。使用29个公开序列的评价表明,我们的方法达到了最先进的精度,在大多数情况下是最准确的SLAM方案。(源码公开)` 28 | * ORB_SLAM3:`ORB_SLAM3:An Accurate Open-Source Library for Visual,Visual-Inertial,and Multimap SLAM 29 | (ORB_SLAM3:一个用于视觉,视觉惯导融合和多地图SLAM的精确开源库) 30 | 摘要:本文介绍了ORB-SLAM3,这是第一个能够使用针孔和鱼眼镜头模型,使用单目、双目和RGB-D相机执行视觉、视觉惯性和多地图 SLAM的系统。第一个主要的创新之处是一个紧密集成的视觉惯性SLAM系统,它完全依赖于最大后验估计(MAP),即使在IMU初始化期间,也能在大小型、室内和室外环境中实现实时鲁棒操作,比以前的方法精确2到10倍。第二个主要的创新之处是多地图系统,它依赖于一种新的位置识别方法和改进的召回,ORB_SLAM3能够在一段弱视觉信息的场景下成功运行:当它丢失时,系统会启用一个新的地图,当访问到之前的区域时,它能与之前的地图进行连接合并。与只使用最后几秒信息的视觉里程计系统相比,ORB-SLAM3是第一个能够在所有算法阶段重用所有先前信息的系统,即使它们时间上相差很远,或者来自之前地图。提高了系统的准确性。 31 | 我们的实验表明,在所有传感器配置中,ORB-SLAM3与现有文献中最好的系统具有一样的鲁棒性,而且明显更精确。值得注意的是,我们的双目惯性SLAM在EuRoC无人机上达到了3.5 cm的平均精度,在TUM-VI数据集(AR/VR场景下),在快速手持动作下达到了9 mm的平均精度。(源码公开)` 32 | ## 视觉slam 33 | ## 回环检测相关项目 34 | - [ov2slam](https://github.com/ov2slam/ov2slam) 35 | - [ibow-lcd](https://github1s.com/emiliofidalgo/ibow-lcd) 36 | - [MILD](https://github.com/lhanaf/MILD) 37 | 38 | ### 基于滤波 39 | * [msckf_mono](https://github.com/daniilidis-group/msckf_mono) 查看[代码](https://github1s.com/daniilidis-group/msckf_mono) 40 | * [openVins](https://docs.openvins.com/gs-installing.html) 41 | 42 | 43 | 44 | ### 基于图优化 45 | * [vins-Mono](https://github.com/HKUST-Aerial-Robotics/VINS-Mono) 46 | * [ORB_SLAM](https://github.com/raulmur/ORB_SLAM) 47 | * [ORB_SLAM2](https://github.com/raulmur/ORB_SLAM2) 48 | * [ORB_SLAM3](https://github.com/UZ-SLAMLab/ORB_SLAM3) 49 | * 50 | 51 | ## 其他优秀slam 52 | 53 | * [gps+imu+eskf](https://github.com/liuqian62/eskf-gps-imu-fusion) 54 | 55 | 56 | ## 激光slam 57 | * legoslam 58 | 59 | ``` 60 | 简介 61 | 62 | ``` 63 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/前缀和.md: -------------------------------------------------------------------------------- 1 | # 前缀和 2 | 3 | ## 目录 4 | 5 | - [DP34](#DP34) 6 | - [DP35](#DP35) 7 | - [DP36](#DP36) 8 | 9 | 10 | ### DP34 11 | * DP34 前缀和 12 | 13 | 描述 14 | ``` 15 | 给定一个长度为n的数组a_1, a_2,....a_n 16 | 接下来有q次查询, 每次查询有两个参数l, r. 17 | 对于每个询问, 请输出a_l+a_{l+1}+....+a_r 18 | 输入描述: 19 | 第一行包含两个整数n和q. 20 | 第二行包含n个整数, 表示a_1, a_2,....a_n 21 | 接下来q行,每行包含两个整数 l和r. 22 | 1≤n,q≤10^5 23 | -10^9 ≤a[i]≤10^9 24 | 1≤l≤r≤n 25 | 输出描述: 26 | 输出q行,每行代表一次查询的结果. 27 | ``` 28 | 29 | ```cpp 30 | #include 31 | using namespace std; 32 | 33 | int main() 34 | { 35 | int n, q; 36 | cin >> n >>q; 37 | vector v(n,0); 38 | vector sum(n+1,0); 39 | for (int i = 0; i < n; i++) { 40 | cin >> v[i]; 41 | sum[i+1]=sum[i]+v[i]; 42 | } 43 | int l,r; 44 | while(cin>>l>>r){ 45 | cout< 52 | ↥ Back To Top 53 | 54 | 55 | 56 | ### DP35 57 | * DP35 二维前缀和 58 | 59 | 描述 60 | ``` 61 | 给你一个 n 行 m 列的矩阵 A ,下标从1开始。 62 | 接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2 63 | 请输出以 (x1, y1) 为左上角 , (x2,y2) 为右下角的子矩阵的和, 64 | 输入描述: 65 | 第一行包含三个整数n,m,q. 66 | 接下来n行,每行m个整数,代表矩阵的元素 67 | 接下来q行,每行4个整数x1, y1, x2, y2,分别代表这次查询的参数 68 | 1≤n,m≤1000 69 | 1≤q≤10^5 70 | -10^9 ≤a[i][j]≤10^9 71 | 1≤x 1 ≤x 2 ≤n 72 | 1≤y 1 ≤y 2 ≤m 73 | 输出描述: 74 | 输出q行,每行表示查询结果。 75 | ``` 76 | 77 | ```cpp 78 | #include 79 | using namespace std; 80 | long long a[1010][1010]; 81 | int main(){ 82 | int n,m,q; 83 | cin>>n>>m>>q; 84 | int i,j; 85 | for(i=1;i<=n;i++){ 86 | for(j=1;j<=m;j++){ 87 | cin>>a[i][j]; 88 | a[i][j]+=a[i-1][j];//行和 89 | } 90 | } 91 | for(j=1;j<=m;j++){ 92 | for(i=1;i<=n;i++)a[i][j]+=a[i][j-1];//列和 93 | } 94 | while(q--){ 95 | int x_1,y_1,x_2,y_2; 96 | cin>>x_1>>y_1>>x_2>>y_2; 97 | cout< 103 | ↥ Back To Top 104 | 105 | 106 | 107 | ### DP36 108 | * DP36 abb 109 | 110 | 描述 111 | ``` 112 | leafee 最近爱上了 abb 型语句,比如“叠词词”、“恶心心” 113 | leafee 拿到了一个只含有小写字母的字符串,她想知道有多少个 "abb" 型的子序列? 114 | 定义: abb 型字符串满足以下条件: 115 | 字符串长度为 3 。 116 | 字符串后两位相同。 117 | 字符串前两位不同。 118 | 119 | 输入描述: 120 | 第一行一个正整数 n 121 | 第二行一个长度为 n的字符串(只包含小写字母) 122 | 1≤n≤10^5 123 | 124 | 输出描述: 125 | "abb" 型的子序列个数。 126 | 127 | ``` 128 | 129 | ```cpp 130 | #include 131 | using namespace std; 132 | long long sum[101010][26]; 133 | int main(){ 134 | int n,i,j; 135 | string s; 136 | cin>>n>>s; 137 | for(i=n-1;i>=0;i--){ 138 | for(j=0;j<26;j++)sum[i][j]=sum[i+1][j]; 139 | sum[i][s[i]-'a']++; 140 | } 141 | long long res=0; 142 | for(i=0;i 155 | ↥ Back To Top 156 | 157 | 158 | -------------------------------------------------------------------------------- /基础四大件/数据结构.md: -------------------------------------------------------------------------------- 1 | # 数据结构 2 | 3 | ## 目录 4 | - [前言](#前言) 5 | - [第一章](#第一章) 6 | - [第二章 线性表(Linear List)](#第二章) 7 | - [第三章 栈和队列(stack and queue)](#第三章) 8 | - [第四章](#第四章) 9 | - [第五章 树和二叉树](#第五章) 10 | - [第六章 图](#第六章) 11 | 12 | 13 | * 前言 14 | * 第一章 15 | * 第二章 线性表(Linear List) 16 | * 第三章 栈和队列(stack and queue) 17 | * 第四章 18 | * 第五章 树和二叉树 19 | * 第六章 图 20 | 21 | 22 | # 前言 23 | ## 基本的数据结构 24 | * 线性结构 25 | * 线性表 26 | * 栈和队列 27 | * 串 28 | * 数组和广义表 29 | * 非线性结构 30 | * 树 31 | * 图 32 | 33 | 34 |
35 | ↥ Back To Top 36 |
37 | 38 | # 第一章 39 | ## 数据结构的研究内容 40 | * 操作对象与操作对象之间的关系 41 | * 非数值计算 42 | ## 数据结构的基本概念和术语 43 | * 数据元素等基本概念 44 | * 数据 45 | * 数值型 46 | * 非数值型 47 | * 数据元素 48 | * 数据的基本单位 49 | * 作为一个整体进行考虑和处理 50 | * 数据项 51 | * 构成数据元素的不可分割的最小单位 52 | * 数据对象 53 | * 性质相同的数据元素的集合,是数据的子集 54 | * 数据结构 55 | * 逻辑结构 56 | * 物理结构(存储结构) 57 | * 顺序存储结构 58 | * 链式存储结构 59 | * 索引存储结构 60 | * 散列存储结构 61 | * 运算和实现 62 | * 数据类型和抽象数据类型 63 | * 数据类型 64 | * 规定了取值范围和所允许的操作 65 | * 抽象数据类型 66 | * 数据对象 67 | * 数据模型(逻辑结构) 68 | * 抽象运算(相关操作) 69 | * 例子 70 | * 构建圆类型 71 | * 构建复数类型 72 | ## 抽象数据类型的表示与实现 73 | * 可以通过固有的数据类型(整型、浮点型...)来表示和实现 74 | * c语言 75 | * 属性 76 | * 函数 77 |
78 | ↥ Back To Top 79 |
80 | 81 | 82 | # 第二章 83 | 线性表(Linear List) 84 | ## 定义和特点 85 | * 具有相同特性的数据元素的一个有限序列 86 | * 直接前驱和直接后继 87 | ## 案例引入 88 | * 一元多项式的运算 89 | * 稀疏多项式的运算 90 | * 遍历每一项 91 | * 指数相同... 92 | * 指数不同... 93 | * 图书信息管理系统 94 | 95 | ## 类型定义 96 | * 数据对象 97 | * 数据关系 98 | * 基本操作 99 | * InitList(&L)初始化 100 | * DestroyList(&L)销毁 101 | * ClearList(&L)重置为空 102 | * ClearList(&L)重置为空 103 | * ListLength(&L)元素个数 104 | * GetElem(L,i,&e)用e返回第i个数据元素 105 | * LocateElem(L,e,ocmpare())查找定位 106 | * PriorElem(L,cur_e,&pre_e)返回前驱 107 | * NextElem(L,cur_e,&next_e)返回后继 108 | * ListInsert(&L,i,e)插入元素 109 | * ListDelete(&L,i,&e)删除元素 110 | * ListTraverse(&L,visited())遍历 111 | ## 顺序表示和实现 112 | * 顺序存储表示 113 | * 地址连续(把逻辑上相邻的数据元素存储在物理上相邻的存储单元中) 114 | * 依次存放(占用连续的存储空间) 115 | * 随机存取(任一元素都可以随机存取) 116 | * 类型相同 117 | * 顺序存储实现 118 | * 构成 119 | * L.elem[0] 120 | * L.length 121 | * 初始化 122 | * 构造一个空的顺序表L 123 | * 为顺序表分配空间 124 | * 如果存储分配失败 125 | * 空表长度为0 126 | * 销毁线性表L 127 | * 释放存储空间 128 | * 清空线性表L 129 | * 将线性表的长度置为0 130 | * 求线性表的长度 131 | * 返回L.length 132 | * 判断是否为空 133 | * L.length==0 134 | * 顺序表的取值 135 | * 判断i值是否合理 136 | * 第i-1的单元存储着第i个数据 137 | * 查找操作 138 | * 遍历 139 | * 比较是否相等 140 | * 返回序号i+1 141 | * 查找失败返回0 142 | * 顺序表的插入 143 | * 判断插入位置i是否合法 144 | * 判断存储空间是否已满 145 | * 将第n至第i位的元素依次向后移动一个位置,空出第i个位置 146 | * 将要插入的元素放入第i个位置 147 | * 顺序表的删除 148 | * 判断删除位置i是否合法 149 | * 将第i+1至第n位的元素依次向前移动一个位置 150 | * 表长减1,删除成功返回OK 151 | * 优缺点 152 | * 优点 153 | * 存储密度大 154 | * 可以随机存取 155 | * 缺点 156 | * 插入、删除时,需要移动大量元素 157 | * 浪费存储空间 158 | * 属于静态存储形式,数据元素的个数不能自由扩充 159 | ## 链式表示和实现 160 | ## 顺序表和链表的比较 161 | ## 应用 162 | ## 案例分析与实现 163 |
164 | ↥ Back To Top 165 |
166 | 167 | 168 | # 第三章 169 | 栈和队列(stack and queue) 170 |
171 | ↥ Back To Top 172 |
173 | 174 | 175 | # 第四章 176 |
177 | ↥ Back To Top 178 |
179 | 180 | 181 | # 第五章 182 | 树和二叉树 183 |
184 | ↥ Back To Top 185 |
186 | 187 | 188 | # 第六章 189 | 图 190 |
191 | ↥ Back To Top 192 |
193 | 194 | 195 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/数位dp.md: -------------------------------------------------------------------------------- 1 | # 数位dp 2 | 3 | ## 目录 4 | 5 | - [DP61](#DP61) 6 | - [DP62](#DP62) 7 | 8 | 9 | 10 | ### DP61 11 | * DP61 串 12 | 13 | 描述 14 | ``` 15 | 长度不超过n,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+7取模。 16 | 所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。 17 | 例如,"unoacscc"包含子序列"us",但"scscucu"则不包含子序列"us" 18 | ``` 19 | 20 | ![img](https://uploadfiles.nowcoder.com/images/20210201/554662_1612175535813/8341171079082A21EC15AC4785FE83A5) 21 | ```cpp 22 | #include 23 | using namespace std; 24 | long long f[1000100][4]; 25 | const int p = 1e9+7; 26 | int n; 27 | int main() 28 | { 29 | long long ans = 0; 30 | cin >> n; 31 | f[1][0] = 25; 32 | f[1][1] = 1; 33 | f[1][2] = 0; 34 | for (int i = 2; i <= n; i++) 35 | { 36 | f[i][0] = (f[i-1][0] * 25) % p;; 37 | f[i][1] = (f[i-1][1] * 25 + f[i-1][0]) % p ; 38 | f[i][2] = (f[i-1][1] + f[i-1][2] * 26) % p ; 39 | ans = (ans+ f[i][2])%p; 40 | } 41 | cout << ans; 42 | return 0; 43 | } 44 | ``` 45 | 46 |
47 | ↥ Back To Top 48 |
49 | 50 | 51 | ### DP62 52 | * DP62 COUNT 数字计数 53 | 54 | 描述 55 | ``` 56 | 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。 57 | 58 | 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。 59 | 输入:1 99 60 | 输出:9 20 20 20 20 20 20 20 20 20 61 | ``` 62 | 63 | 我们设dp[i][j][k]表示长度为i,开头为j的数中k的个数,一开始就推算dp数组中每个元素的值,可以枚举所有长度为iii的数字中首位和第二位的数字, 64 | 有dp[i][j][z]+=dp[i−1][k][z],其中iii为数字位数,jjj为开头的数字,kkk为上一个长度开头的数字,zzz为当前要统计的数码。 65 | 然后我们找到1到b的答案减去1到a-1答案,在找的时候分开统计答案,对于位数小于当前数的直接全部加上,剩余的拆分统计。 66 | 67 | ```cpp 68 | #include 69 | #include 70 | #include 71 | using namespace std; 72 | 73 | const int maxn = 15; //最大数字不超过12位 74 | long long dp[maxn][maxn][maxn]; //十进制数中长度为i,开头为j的数中k的个数 75 | long long bin[maxn]; //i位中所有首位为i的数的个数 76 | long long res[maxn]; //记录0~9个数 77 | int d[maxn]; 78 | 79 | void init(){ //递推计算出每个整数 80 | bin[1] = 1; //1位首位为1只有1个 81 | for(int i = 2; i <= 13; i++) //后续都是前一个的10倍 82 | bin[i] = bin[i - 1] * 10; 83 | for(int i = 0; i <= 9; i++) //长度为1,以i开头中i的个数都是1 84 | dp[1][i][i]=1; 85 | for(int i = 2; i <= 13; i++) 86 | for(int j = 0; j <= 9; j++) 87 | for(int z = 0; z <= 9; z++){ 88 | for(int k = 0; k <= 9; k++) 89 | dp[i][j][z] += dp[i - 1][k][z]; //累加前面的 90 | dp[i][z][z] += bin[i - 1]; 91 | } 92 | } 93 | 94 | void solve(long long x,int flag){ //计算1到x的所有数码出现次数 95 | int dnum = 0; //记录当前数的位数 96 | long long y = x; 97 | memset(d, 0, sizeof(d)); 98 | while(y){ //连除法计算当前x的位数 99 | d[++dnum] = y % 10; 100 | y /= 10; 101 | } 102 | for(int i = 1; i <= dnum - 1; i++)//先计算位数小于当前数的位数 103 | for(int j = 1; j <= 9; j++) 104 | for(int k = 0; k <= 9; k++) 105 | res[k] += (dp[i][j][k] * flag); //累加,flag为1加,-1为减 106 | int temp = dnum; 107 | while(temp){//再计算位数等于当前数的位数 108 | for(int i = 0; i < d[temp]; i++){ 109 | if(!i && temp == dnum) 110 | continue;//不能重复计算 111 | for(int j = 0; j <= 9; j++) 112 | res[j] += (dp[temp][i][j] * flag); 113 | } 114 | res[d[temp]] += (x % bin[temp] + 1) * flag; 115 | temp--; 116 | } 117 | } 118 | 119 | int main(){ 120 | init(); 121 | long long a, b; 122 | cin >> a >> b; 123 | solve(b, 1); //计算1到b的所有数码次数 124 | solve(a - 1, -1); //减去1到a-1的所有数码出现次数 125 | for(int i = 0; i <= 9; i++) //输出 126 | cout << res[i] << " "; 127 | cout << endl; 128 | return 0; 129 | } 130 | ``` 131 | 132 |
133 | ↥ Back To Top 134 |
135 | 136 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/贪心算法.md: -------------------------------------------------------------------------------- 1 | # 贪心算法 2 | 3 | ## 目录 4 | 5 | 6 | - [BM95](#BM95) 7 | - [BM96](#BM96) 8 | 9 | 10 | 11 | ## BM95 12 | * BM95 分糖果问题 13 | 14 | 描述 15 | ``` 16 | 一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下: 17 | 18 | 1. 每个孩子不管得分多少,起码分到一个糖果。 19 | 2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制) 20 | 21 | 给定一个数组 arrarr 代表得分数组,请返回最少需要多少糖果。 22 | 23 | 要求: 时间复杂度为 O(n)O(n) 空间复杂度为 O(n)O(n) 24 | 25 | 数据范围: 1 \le n \le 1000001≤n≤100000 ,1 \le a_i \le 10001≤a 26 | i 27 | ​ 28 | ≤1000 29 | ``` 30 | 31 | ``` 32 | 知识点:贪心思想 33 | 34 | 贪心思想属于动态规划思想中的一种,其基本原理是找出整体当中给的每个局部子结构的最优解,并且最终将所有的这些局部最优解结合起来形成整体上的一个最优解。 35 | 36 | 思路: 37 | 38 | 要想分出最少的糖果,利用贪心思想,肯定是相邻位置没有增加的情况下,大家都分到1,相邻位置有增加的情况下,分到糖果数加1就好。什么情况下会增加糖果,相邻位置有得分差异,可能是递增可能是递减,如果是递增的话,糖果依次加1,如果是递减糖果依次减1?这不符合最小,因为减到最后一个递减的位置可能不是1,必须从1开始加才是最小,那我们可以从最后一个递减的位置往前反向加1. 39 | 40 | 具体做法: 41 | 42 | step 1:使用一个辅助数组记录每个位置的孩子分到的糖果,全部初始化为1. 43 | step 2:从左到右遍历数组,如果右边元素比相邻左边元素大,意味着在递增,糖果数就是前一个加1,否则保持1不变。 44 | step 3:从右到左遍历数组,如果左边元素比相邻右边元素大, 意味着在原数组中是递减部分,如果左边在上一轮中分到的糖果数更小,则更新为右边的糖果数+1,否则保持不变。 45 | step 4:将辅助数组中的元素累加求和。 46 | ``` 47 | ![img](https://uploadfiles.nowcoder.com/images/20220221/397721558_1645407818866/A8400E6DCC3AEA3DA7A76AE52585741A) 48 | ```cpp 49 | class Solution { 50 | public: 51 | int candy(vector& arr) { 52 | //记录每个位置的糖果数,初始为1 fast-template 53 | vector nums(arr.size(), 1); 54 | //从左到右遍历 55 | for (int i = 1; i < arr.size(); i++) { 56 | //如果右边在递增,每次增加一个 57 | if (arr[i] > arr[i - 1]) 58 | nums[i] = nums[i - 1] + 1; 59 | } 60 | //记录总糖果数 61 | int res = nums[arr.size() - 1]; 62 | //从右到左遍历 63 | for (int i = arr.size() - 2; i >= 0; i--) { 64 | //如果左边更大但是糖果数更小 65 | if (arr[i] > arr[i + 1] && nums[i] <= nums[i + 1]) 66 | nums[i] = nums[i + 1] + 1; 67 | //累加和 68 | res += nums[i]; 69 | } 70 | return res; 71 | } 72 | }; 73 | ``` 74 | 75 |
76 | ↥ Back To Top 77 |
78 | 79 | 80 | 81 | ## BM96 82 | * BM96 主持人调度(二) 83 | 84 | 描述 85 | ``` 86 | 有 n 个活动即将举办,每个活动都有开始时间与活动的结束时间,第 i 个活动的开始时间是 starti ,第 i 个活动的结束时间是 endi ,举办某个活动就需要为该活动准备一个活动主持人。 87 | 88 | 一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i 个活动,那么该主持人在 (starti,endi) 这个时间段不能参与其他任何活动。求为了成功举办这 n 个活动,最少需要多少名主持人。 89 | 90 | 数据范围: 1 \le n \le 10^51≤n≤10 91 | 5 92 | , -2^{32} \le start_i\le end_i \le 2^{31}-1−2 93 | 32 94 | ≤start 95 | i 96 | ​ 97 | ≤end 98 | i 99 | ​ 100 | ≤2 101 | 31 102 | −1 103 | 104 | 复杂度要求:时间复杂度 O(n \log n)O(nlogn) ,空间复杂度 O(n)O(n) 105 | ``` 106 | 107 | ```cpp 108 | class Solution { 109 | public: 110 | /** 111 | * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 112 | * 113 | * 计算成功举办活动需要多少名主持人 114 | * @param n int整型 有n个活动 115 | * @param startEnd int整型vector> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间 116 | * @return int整型 117 | */ 118 | int minmumNumberOfHost(int n, vector >& startEnd) { 119 | // write code here 120 | vector start,end; 121 | for(int i = 0;i 146 | ↥ Back To Top 147 | 148 | 149 | -------------------------------------------------------------------------------- /slamNotes/SLAM面试问题整理.md: -------------------------------------------------------------------------------- 1 | # slam面试相关问题 2 | 来源:[牛客网](https://www.nowcoder.com/discuss/871117?type=all&order=recall&pos=&page=0&ncTraceId=&channel=-1&source_id=search_all_nctrack&gio_id=BE866F1A547D63ED6F3DAFAEBEAF22DF-1652589160166) 3 | ## Case1 4 | 一面 5 | ``` 6 | 项目相关 7 | 1、简历中的项目相关问题,项目是三维重建相关的,深度学习的深度估计 8 | 2、具体细节上,网络结构、loss设计、数据、训练泛化效果 9 | 3、非公共区域如何处理、精度如何保证 10 | 基础: 11 | 1、非线性优化 12 | 2、视觉slam基础 13 | 场景题: 14 | 1、只有相机的情况下,采用深度学习的方案,如何实现高精度、强泛化的模型效果 15 | 2、cnn,不做三维了,做其他方向,怎么准备 16 | ``` 17 | 18 | 二面 19 | ``` 20 | 简历中的项目相关问题 21 | 基础: 22 | 三维相关: 23 | 1、双目立体匹配,哪些方案 24 | 2、sgbm,全称,g是如何实现的,什么算法原理 25 | 3、kinectfusion等等开源三维重建框架,有没有玩过,看过 26 | 深度学习相关: 27 | 1、cnn 基础架构哪些,cnn总体可以分为哪两类任务 28 | 2、l1 l2 loss 优缺点、原因、l1 l2正则化,优点,原因,如何在pytorch代码里面实现 29 | 3、交叉熵loss,代码,二分类问题 30 | 4、多loss加和,如何实现自适应权重调节 31 | 5、transformer 32 | 6、目前的模型是在什么上面跑的,tensorRT搞没搞过,有没有用c++载入过模型,模型太大怎么办,网络结构怎么调 33 | 7、轻量级网络架构哪些,mobilenet知不知道 34 | slam相关: 35 | 1、E矩阵 F矩阵,全称,至少需要几对点来计算,自由度、矩阵的秩 36 | 2、什么情况下无法正确计算E矩阵,为什么 37 | 3、ransac,ransac特殊形式 38 | 4、pnp问题,至少需要几对点,为什么很少的点就可以计算了,还需要那么多匹配对 39 | 5、orbslam相关,orbslam流程,fast关键点、brief描述子、旋转不变性、怎么实现三角化 40 | 6、5的1/3次方怎么算,只有加减乘除 41 | 7、非线性优化、牛顿法、高斯牛顿法、区别,各是几阶的,本质区别 42 | ``` 43 | ## Case2 44 | 一面 45 | ``` 46 | 47 | 48 | 1、简历中的项目相关问题,项目思想,展开讨论 49 | 2、选一个最熟悉的开源框架讲讲 50 | 3、当你写BA的时候, 如果发现问题,你一般怎么debug 51 | 4、ORBSLAM还有什么改进的空间除了回环检测之外,orbslam怎么消除累计误差 52 | ``` 53 | 二面 54 | ``` 55 | 1、项目中的code 56 | 2、讲一下lamda函数 57 | 3、虚函数表 58 | 4、两道代码题,一道是用类来实现一个计时器。另一道是动态规划题。 59 | 5、根据编程中的知识点问一些问题,类的生存周期,类的内存储存在哪? 60 | ``` 61 | ## Case3 62 | 63 | ``` 64 | 65 | 1、自我介绍 66 | 2、写一个梯度下降法求解a^2=b的算法题 67 | 3、简历中的项目相关问题,尤其探讨了深度学习相关的知识在检测和分割领域的应用 68 | 4、ORB-SLAM2单目的初始化,VINS-MONO的初始化。主要涉及到一些基础知识的问答 69 | ``` 70 | 71 | ## Case4 72 | 73 | ``` 74 | 1、详细讲一下cartographer的流程 75 | 2、在无人机上跑的时候计算平台是什么样的,carto在上面跑的时候的资源占用 76 | 3、你的3DSLAM主要用在什么上面 77 | 4、在无人机上做和在车上做有什么区别 78 | 5、简历上说熟悉loam,lego-loam,说说loam和lego-loam的区别 79 | 6、两步L-M和loam的一步有什么区别 80 | 7、你说lego-loam回环比较简单,你有了解过什么更好的吗 81 | 8、IMU和激光融合做的算法有没有了解 82 | 9、IMU和激光雷达紧耦合的开源项目有没有了解 83 | 10、IMU预积分有没有了解 84 | 11、激光雷达怎么判断适合你的使用的,即选型,你会看那些参数 85 | 12、假如让你用EKF做IMU和激光雷达的融合怎么做 86 | 13、简历上说熟悉非线性优化G-N/L-M,平时主要用那种 87 | 14、调的库还是自己写的 88 | 15、L-M跟G-N有什么区别 89 | 16、看你也有用ceres库,huber是怎么设置的 90 | 17、说说项目,EKF怎么调参的,调完有什么感想、心得 91 | ``` 92 | ## Case5 93 | 一面 94 | ``` 95 | 1、简历中的项目相关问题 96 | 2、光流原理 97 | 3、矩阵求逆的复杂度?矩阵分解有哪些方法,复杂度是多少?工程上哪种方法最通用,为什么? 98 | 4、H和F矩阵的自由度。 99 | 5、IMU预积分了解吗? 100 | 6、MLE和MAP的关系。 101 | ``` 102 | 二面 103 | ``` 104 | 1、三道代码题,hashmap,动态规划相关。 105 | 2、C++11如何有效防止内存泄***r /> 3、智能指针,weak_ptr讲一下 106 | 4、array和数组有什么区别? 107 | 5、C++如何高效管理动态内存(关于这个问题我真的很迷) 108 | ``` 109 | 三面 110 | ``` 111 | 1、简历中的项目相关问题。 112 | 2、opencv、eigen、PCL库了解吗?PCL库里bug挺多,你说说有哪些bug。 113 | 3、ORBSLAM的代码有哪些需要改进的地方? 114 | 4、BA中,海塞矩阵的求逆有哪些可以加速的方法,除了边缘化和GPU,有哪些数值计算的方式能够加速? 115 | 5、ceres库的自动求解雅克比的原理? 116 | 6、ROS中,node属于多进程,如何把两个node放在一个进程中? 117 | ``` 118 | ## Case6 119 | 一面 120 | ``` 121 | 1、长廊问题怎么办? 122 | 2、为什要选用yolo这个模型? 123 | 3、动态SLAM的思路?与基础矩阵分割相比有什么区别?什么是三角剖分?与深度学习方法相比的优势? 124 | 4、霍夫变换的原理?单应矩阵为什么只有8个自由度? 125 | 5、RANSAC 126 | 6、ORBSLAM的初始化步骤 127 | 7、怎么用H的稀疏性加速? 128 | 8、滑动窗口中的边缘化? 129 | 9、R的性质,李群 130 | ``` 131 | 二面 132 | ``` 133 | 1、纯代码面,手撕两道编程题。记得其中一道与flood fill类似。 134 | 2、git的基本原理以及相关操作 135 | 3、还有一些C++基本知识 136 | ``` 137 | 三面 138 | ``` 139 | 1、PnP求解最少需要几个点?(4个,3个求解,1个验证)只有一个点的自由度是多少?两个点呢? 140 | 2、二维码恢复相对位置,六个自由度,哪个自由度上对噪声比较敏感? 141 | 3、怎么用EKF融合多传感器信息? 142 | 4、单目视觉如何测量深度? 143 | 5、相机内参K的单位。 144 | 6、如何通过光流一致性剔除动态物体? 145 | ``` 146 | ## Case7 147 | 一面 148 | ``` 149 | 1、简历中的项目相关问题,多传感器融合了解吗? 150 | 2、跑过哪些开源算法,是否做过对比,各有什么优劣? 151 | 3、对于光照明暗变化、动态场景,视觉SLAM如何去解决? 152 | 4、视觉SLAM的行业应用有哪些,阐述一下语义SLAM的未来应用优势与劣势? 153 | ``` 154 | 二面 155 | ``` 156 | 1、做了哪些项目,问得非常细,会抠项目的细节问。 157 | 2、你做的项目未来还有什么改进点? 158 | 3、一道编程题,位运算相关。 159 | ``` 160 | ## Case8 161 | 一面 162 | ``` 163 | 1、简历中的项目相关问题 164 | 2、ORBSLAM的哪个部分最耗时?后端H矩阵求解的算法复杂度是多少?如何去加速后端求解? 165 | 3、如何求解线性方程Ax=b?SVD和QR分解哪个更快? 166 | ``` 167 | 二面 168 | ``` 169 | 170 | 1、ORBSLAM怎么克服尺度漂移问题?回环原理讲一下,要估计哪些量? 171 | 2、做了一道题,嵌入式编程相关,设计位运算。 172 | 3、嵌入式方面,DRAM和SRAM的区别,速度差多少? 173 | 4、因为项目用了TX2,问到TX2有哪些模块? 174 | ``` 175 | -------------------------------------------------------------------------------- /learnCpp/readme.md: -------------------------------------------------------------------------------- 1 | # These are my notes while learning c++. 2 | 3 | # 目录 4 | - [算法基础篇](#算法基础篇) 5 | - [算法基本应用篇](#算法基本应用篇) 6 | - [算法高级应用篇](#算法高级应用篇) 7 | 8 | - [代码随想录笔记](代码随想录.md) 9 | - [面经八股文](面经八股文.md) 10 | 11 | 12 | --- 13 | ## [大佬对所有算法的总结1](https://blog.csdn.net/u011815404/article/details/79919616?spm=1001.2014.3001.5502) 14 | ## [大佬对所有算法的总结2](https://blog.csdn.net/u011815404/article/details/79324003?spm=1001.2014.3001.5502) 15 | 16 | ## 黑马C++教程 17 | * [视频教程](https://www.bilibili.com/video/BV1et411b73Z?p=1) 18 | * [基础入门](https://blog.csdn.net/ClaireSy/article/details/120155878?spm=1001.2014.3001.5502) 19 | * [核心编程](https://blog.csdn.net/ClaireSy/article/details/108423047) 20 | * [提高编程](https://blog.csdn.net/ClaireSy/article/details/108423061) 21 | --- 22 | 23 | 24 | 25 | # 算法基础篇 26 | 27 | ## 1. 算法概述 28 | 29 | ### 5个特性 30 | 31 | * 有穷性 32 | * 确切性 33 | * 输入 34 | * 输出 35 | * 可执行 36 | 37 | ### 算法分类 38 | 39 | #### 按应用分 40 | * 基本算法 41 | * 数据结构相关算法 42 | * 几何算法 43 | * 图论算法 44 | * 规划算法 45 | * 数值分析算法 46 | * 加密/解密算法 47 | * 排序算法 48 | * 查找算法 49 | * 并行算法 50 | * 数论算法 51 | 52 | #### 按确定性分 53 | * 确定性算法 54 | * 非确定性算法 55 | 56 | #### 按算法思路分 57 | * 递推算法 58 | * 递归算法 59 | * 穷举算法 60 | * 贪婪算法 61 | * 分治算法 62 | * 动态规划算法 63 | * 迭代算法 64 | 65 | #### 算法的表示 66 | * 自然语言表示 67 | * 流程图表示 68 | * N-S图表示 69 | * 伪代码表示 70 | 71 | #### 算法的性能评价 72 | * 时间复杂度 73 | * 空间复杂度 74 | 75 | ## 2. 数据结构 76 | ### 数据结构概述 77 | ### 线性表 78 | ### 顺序表 79 | ### 链表 80 | ### 栈 81 | ### 队列 82 | ### 树 83 | ### 图 84 |
85 | ↥ Back To Top 86 |
87 | 88 | 89 | ## 3. 基本算法思想 90 | * 穷举算法思想 91 | 92 | 穷 举 算 法 (ExhaustiveA ttack method)是 最 简 单 的 一 种 算 法 ,其依赖于计算机的强大计算能力来 穷 尽 每 一 种 可 能 的 情 况 ,从 而 达 到 求 解 问 题 的 目 的 。穷 举 算 法 效 率 并 不 高 ,但是适应于一 些没有明 显 规 律 可 循 的 场 合。 93 | 94 | * 递推算法思想 95 | 96 | * 递归算法思想 97 | 98 | * 分治算法思想 99 | 100 | * 概率算法思想 101 |
102 | ↥ Back To Top 103 |
104 | 105 | 106 | 107 | # 算法基本应用篇 108 | 109 | ## 4. 排序算法 110 | ### 排序算法概述 111 | ### 冒泡排序法 112 | ### 选择排序法 113 | ### 插入排序法 114 | ### Shell排序法 115 | ### 快速排序法 116 | ### 堆排序法 117 | ### 合并排序法 118 |
119 | ↥ Back To Top 120 |
121 | 122 | 123 | ## 5. 查找算法 124 | ### 查找算法概述 125 | ### 顺序查找 126 | ### 折半查找 127 | ### 数据结构中的查找算法 128 |
129 | ↥ Back To Top 130 |
131 | 132 | 133 | ## 6. 基本数学问题 134 | ### 判断闰年 135 | ### 多项式计算 136 | ### 随机数生成算法 137 | ### 复数运算 138 | ### 阶乘 139 | ### 计算圆周率的近似值 140 | ### 矩阵运算 141 | ### 方程求解 142 |
143 | ↥ Back To Top 144 |
145 | 146 | 147 | ## 7. 复杂的数值计算方法 148 | ### 拉格朗日插值 149 | ### 数值积分 150 | ### 开平方 151 | ### 极值问题的求解算法 152 | ### 特殊函数的计算算法 153 |
154 | ↥ Back To Top 155 |
156 | 157 | 158 | ## 8. 经典数据结构问题 159 | ### 动态数组排序 160 | ### 约瑟夫环 161 | ### 城市之间的最短总距离 162 | ### 最短路径 163 | ### 括号匹配 164 |
165 | ↥ Back To Top 166 |
167 | 168 | 169 | ## 9. 数论问题 170 | ### 数论 171 | ### 完全数 172 | ### 亲密数 173 | ### 水仙花数 174 | ### 自守数 175 | ### 最大共约数 176 | ### 最小公倍数 177 | ### 素数 178 | ### 回文数 179 | ### 平方回文数 180 | ### 分解质因素 181 |
182 | ↥ Back To Top 183 |
184 | 185 | 186 | ## 10. 算法经典趣题 187 | ### 百钱买百鸡 188 | ### 五家共井 189 | ### 鸡兔同笼 190 | ### 猴子吃桃 191 | ### 舍罕王赏麦 192 | ### 汉诺塔 193 | ### 窃贼问题 194 | ### 马踏棋盘 195 | ### 八皇后问题 196 | ### 寻找假银币 197 | ### 青蛙过河 198 | ### 三色旗 199 | ### 渔夫捕鱼 200 | ### 爱因斯坦的阶梯 201 | ### 兔子产仔 202 | ### 常胜将军 203 | ### 新郎和新粮 204 | ### 三色球 205 |
206 | ↥ Back To Top 207 |
208 | 209 | 210 | ## 11. 游戏中的算法 211 | ### 洗扑克牌 212 | ### 取火柴游戏 213 | ### 10点半 214 | ### 生命游戏 215 |
216 | ↥ Back To Top 217 |
218 | 219 | 220 | 221 | # 算法高级应用篇 222 | 223 | 224 | ## 12. 密码学算法 225 | ### 密码学概述 226 | ### 换位加密解密 227 | ### 替换加密解密 228 | ### 位加密解密 229 | ### 一次一密加密解密 230 | 231 |
232 | ↥ Back To Top 233 |
234 | 235 | ## 13. 压缩与解压算法 236 | ### 压缩与解压缩概述 237 | ### 压缩算法 238 | ### 解压缩算法 239 | 240 |
241 | ↥ Back To Top 242 |
243 | 244 | # 常用的10种算法 245 | 246 | * 二分查找 247 | 248 | * 分治算法 249 | 250 | * 动态规划 251 | 252 | * KMP算法 253 | 254 | * 贪心算法 255 | 256 | * 普利姆算法 257 | 258 | * 克鲁斯卡尔算法 259 | 260 | * 迪杰特斯拉算法 261 | 262 | * 弗洛伊德算法 263 | 264 | * 马踏棋盘算法 265 | 266 |
267 | ↥ Back To Top 268 |
269 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/状压dp.md: -------------------------------------------------------------------------------- 1 | # 状压dp 2 | 3 | ## 目录 4 | 5 | - [DP59](#DP59) 6 | - [DP60](#DP60) 7 | 8 | ### DP59 9 | * DP59 数位染色 10 | 11 | 描述 12 | ``` 13 | 小红拿到了一个正整数 x\x 。她可以将其中一些数位染成红色。然后她想让所有染红的数位数字之和等于没染色的数位数字之和。 14 | 她不知道能不能达成目标。你能告诉她吗? 15 | 16 | 输入描述: 17 | 一个正整数 x,1≤x≤10^18 18 | 19 | 20 | 输出描述: 21 | 如果小红能按要求完成染色,输出"Yes"。否则输出"No"。 22 | 23 | ``` 24 | 25 | 具体做法 26 | ``` 27 | 首先使用连除法将nnn的每位数字依次记录在数组中,并在这个过程中求得所有位数之和,那我们要找的就是能否在这个数组中找到诺干个数字加起来等于位数之和的一半。 28 | 29 | 首先排除和为奇数的情况,无法构成一半。然后我们用一个长度为和一半的dp数组,dp[i]不为0表示和为iii的情况是可以被找到的,为0代表找不到,初始化都为0。 30 | 我们遍历数组中记录的每位数字sum[i],每次再遍历sum/2到该数字,如果dp[j]可以被相加得到,说明j−sum[i]已经得到了,或者在之前的遍历中得到过, 31 | 于是就有转移方程dp[j]=dp[j]+dp[j−num[i]],最后我们检查dp[sum/2]是否为0即可。 32 | ``` 33 | ![img](https://uploadfiles.nowcoder.com/images/20211101/397721558_1635768819545/785D47AB0FD8801B29F0E87B4F5BD5EF) 34 | ```cpp 35 | #include 36 | using namespace std; 37 | 38 | int main(){ 39 | string s; 40 | cin>>s; 41 | vector num; //记录数每位 42 | int sum = 0; 43 | for(int i=0;i dp(sum / 2 + 1, 0); //dp[i]不为0,表示dp[i]可以被选出的数字相加得到 53 | dp[0] = 1; 54 | for(int i = 0; i < num.size(); i++){ 55 | for(int j = sum / 2; j >= num[i]; j--) 56 | dp[j] = dp[j] + dp[j - num[i]]; //能够被这两个数相加得到 57 | } 58 | if(dp[sum / 2]) //不为0 59 | cout << "Yes" << endl; 60 | else 61 | cout << "No" << endl; 62 | return 0; 63 | } 64 | ``` 65 | 66 |
67 | ↥ Back To Top 68 |
69 | 70 | 71 | ### DP60 72 | * DP60 郊区春游 73 | 74 | 描述 75 | ``` 76 | 今天春天铁子的班上组织了一场春游,在铁子的城市里有n个郊区和m条无向道路,第i条道路连接郊区Ai和Bi,路费是Ci。经过铁子和顺溜的提议, 77 | 他们决定去其中的R个郊区玩耍(不考虑玩耍的顺序),但是由于他们的班费紧张,所以需要找到一条旅游路线使得他们的花费最少, 78 | 假设他们制定的旅游路线为V1, V2 ,V3 ... VR,那么他们的总花费为从V1到V2的花费加上V2到V3的花费依次类推, 79 | 注意从铁子班上到V1的花费和从VR到铁子班上的花费是不需要考虑的,因为这两段花费由学校报销而且我们也不打算告诉你铁子学校的位置。 80 | 输入描述: 81 | 第一行三个整数n, m, R(2 ≤ n ≤ 200, 1 ≤ m ≤ 5000, 2 ≤ R ≤ min(n, 15))。 82 | 第二行R个整数表示需要去玩耍的郊区编号。 83 | 以下m行每行Ai, Bi, Ci(1 ≤ Ai, Bi ≤ n, Ai ≠ Bi, Ci ≤ 10000) 84 | 保证不存在重边。 85 | 输出描述: 86 | 输出一行表示最小的花费 87 | 88 | 89 | ``` 90 | 91 | 具体做法 92 | ``` 93 | 94 | 首先我们用邻接矩阵来表示这个图,矩阵记录两两点之间的距离,初始化为最大值,自己到自己都是0,再根据输入更新直接连接的两个点的距离,然后遍历所有的两两的点,更新所有的点之间的最短距离,得到的点之间的距离都是最短的。 95 | 96 | 然后我们用dp[i][j]dp[i][j]dp[i][j]表示状态值为iii、以jjj号地为终点的所有距离最小值,其中状态值是指我们用二进制的形式表示这个地方有没有走过,走过就是1,没走过就是0,一共需要2R2^R2 97 | R 98 | 个位置来表示所有状态,我们用数组代替。 99 | 100 | 初始化的时候,每个点都是结束,但也只去过这个点,因此自己到自己始终都是0。后续我们枚举所有的状态,对每个状态枚举所有的起始位置和结束位置(需要排除刚刚初始化的位置),然后更新状态: dp[(1< 105 | using namespace std; 106 | 107 | const int INF = 0x3f3f3f3f; 108 | int main(){ 109 | int n, m, R; 110 | cin >> n >> m >> R; 111 | vector visit(R); //需要去的R个郊区 112 | for(int i = 0; i < R; i++) 113 | cin >> visit[i]; 114 | vector> edges(n + 1, vector(n + 1, INF)); //邻接矩阵记录边的花费 115 | for(int i = 1; i <= n; i++) 116 | edges[i][i] = 0; // 自己到自己是0 117 | for(int i = 0; i < m; i++){ 118 | int a, b, c; 119 | cin >> a >> b >> c; 120 | edges[a][b] = c; //构建边的花费 121 | edges[b][a] = c; 122 | } 123 | for(int k = 1; k <= n; k++){ //获取每两两结点间的距离花费 124 | for(int i = 1; i <= n; i++){ 125 | for(int j = 1; j <= n; j++){ 126 | if(edges[i][j] > edges[i][k] + edges[k][j]) 127 | edges[i][j] = edges[i][k] + edges[k][j]; //更新两两之间的花费为更小的值 128 | } 129 | } 130 | } 131 | vector > dp(1 << R, vector(R + 1, INF)); 132 | for(int i = 0; i < R; i++) 133 | dp[1 << i][i] = 0; //最开始走的那个,没有花费 134 | for(int i = 1; i < (1 << R) - 1; i++){ //枚举所有的状态 135 | for(int j = 0; j < R; j++){ //每个状态的所有起始位置 136 | if((1 << j) & i == 0) //走过了最开始位置 137 | continue; 138 | for(int k = 0; k < R; k++) //更新终点位置 139 | dp[(1 << k) | i][k] = min(dp[(1 << k) | i][k], dp[i][j] + edges[visit[j]][visit[k]]); 140 | } 141 | } 142 | int mincost = INT_MAX; 143 | for(int i = 0; i < R; i++) //获取每个位置为结束的最小花费 144 | mincost = min(mincost, dp[(1 << R) - 1][i]); 145 | cout << mincost << endl; 146 | return 0; 147 | } 148 | ``` 149 | 150 |
151 | ↥ Back To Top 152 |
153 | 154 | 155 | -------------------------------------------------------------------------------- /slamNotes/ros常用消息.md: -------------------------------------------------------------------------------- 1 | # ROS 中内置消息类型 2 | 3 | ## std_msgs 4 | 5 | ### 单类型 6 | 7 | 8 | 9 | ### 数组类型 10 | 11 | 12 | 13 | ### Head 14 | 15 | std_msg中还包含一个特殊消息类型 :Head,表示包头,它是一个结构体,内置三个类型: 16 | 17 | ```cpp 18 | uint32 seq # 表示数据流的 sequenceID 19 | time stamp # 表示时间戳 20 | string frame_id # 表示当前帧数据的帧头(帧序号) 21 | ``` 22 | 23 | 24 | 25 | Head类型常用于记录每帧数据的时间和序列信息,用于记录历史数据的情形。 26 | 27 | 以上消息类型是其他各种类型的基础,其他各种消息类型的嵌套定义归根结底都依赖以上几种类型。 28 | 29 | 30 | 31 | ## comm_msg 32 | 33 | 源代码:https://github.com/ros/common_msgs 34 | 35 | 该类型是ros常用数据类型的集合,包括以下几种:actionlib_msgs、diagnostic_msgs、geometry_msgs、nav_msgs、sensor_msgs, 下面是几种最常用的类型的介绍: 36 | 37 | ### geometry_msgs 38 | 39 | 是最常用的几何消息类型,定义了描述机器人状态的各种类型,比如点、速度、加速度、位姿等。 40 | 41 | 42 | 43 | #### Vector3、Vector3Stamped 44 | 45 | * geometry_msgs/Vector3.msg 46 | 47 | 表示自由空间的三维向量,是一个结构体,内置三个类型: 48 | 49 | ```cpp 50 | float64 x 51 | float64 y 52 | float64 z 53 | ``` 54 | 55 | 56 | 57 | 注意:该类型仅用于表示方向,tf2中只能应用于(rotation)旋转,不能应用于变换(transtion),若想用于变换,需要用到geometry_msgs/Point类型。 58 | 59 | * geometry_msgs/Vector3Stamped.msg 60 | 61 | 表示带有时间戳和参考坐标系的三维向量 62 | 63 | ```cpp 64 | std_msgs/Header header 65 | geometry_msgs/Vector3 vector 66 | ``` 67 | 68 | 69 | 70 | #### Quaternion、QuaternionStamped 71 | 72 | * geometry_msgs/Quaternion.msg 73 | 74 | 用四元数表示自由空间中的旋转: 75 | 76 | ```cpp 77 | float64 x 78 | float64 y 79 | float64 z 80 | float64 w 81 | ``` 82 | 83 | 84 | 85 | * geometry_msgs/QuaternionStamped.msg 86 | 87 | 表示带有参考坐标系和时间戳的旋转: 88 | 89 | ```cpp 90 | std_msgs/Header header 91 | geometry_msgs/Quaternion quaternion 92 | ``` 93 | 94 | 95 | 96 | #### Transform、TransformStamped 97 | 98 | * geometry_msgs/Transform.msg 99 | 100 | 表示自由空间的两个坐标系之间的变换关系,包括旋转和平移。旋转用四元数表示,平移用平移向量表示: 101 | 102 | ```cpp 103 | geometry_msgs/Vector3 translation 104 | geometry_msgs/Quaternion rotation 105 | ``` 106 | 107 | * geometry_msgs/TransformStamped.msg 108 | 109 | 表示从Head里面的坐标系到子坐标系的变换: 110 | 111 | ```cpp 112 | std_msgs/Header header 113 | string child_frame_id #子坐标系 114 | geometry_msgs/Transform transform 115 | ``` 116 | 117 | #### Point、Point32、PointStamped 118 | 119 | * geometry_msgs/Point.msg 120 | 121 | 表示自由空间中的点: 122 | 123 | ```cpp 124 | float64 x 125 | float64 y 126 | float64 z 127 | ``` 128 | 129 | * geometry_msgs/Point32.msg 130 | 131 | 为了在发送点云时减少数据量,ros提供了压缩版的point32: 132 | 133 | ```cpp 134 | float32 x 135 | float32 y 136 | float32 z 137 | ``` 138 | 139 | * geometry_msgs/PointStamped.msg 140 | 141 | 带有参考坐标系和时间戳的point: 142 | 143 | ```cpp 144 | std_msgs/Header header 145 | geometry_msgs/Point point 146 | ``` 147 | 148 | #### Pose、Pose2D、PoseArray、PoseStamped、PoseWithCovariance、PoseWithCovarianceStamp 149 | 150 | * geometry_msgs/Pose.msg 151 | 152 | 位姿,即位置和姿态,用point表示位置,用四元数表示姿态: 153 | 154 | ```cpp 155 | geometry_msgs/Point position 156 | geometry_msgs/Quaternion orientation 157 | ``` 158 | 159 | * geometry_msgs/Pose2D.msg 160 | 161 | 表示二维平面上面的一个点(表示2D流形上的位置和方向): 162 | 163 | ```cpp 164 | float64 x 165 | float64 y 166 | float64 theta 167 | ``` 168 | 169 | * geomtry_msgs/PoseArray.msg 170 | 171 | 表示全局坐标系下的一组轨迹点: 172 | 173 | ```cpp 174 | std_msgs/Header header #head里面保存了参考系 175 | geometry_msgs/Pose[] poses 176 | ``` 177 | 178 | * geometry_msgs/PoseStamped.msg 179 | 180 | 表示带有时间戳和参考系的位姿: 181 | 182 | ```cpp 183 | std_msgs/Header header 184 | geometry_msgs/Pose pose 185 | ``` 186 | 187 | * geometry_msgs/PoseWithCovariance.msg 188 | 189 | 表示带有协方差矩阵的位姿估计,协方差矩阵表示其不确定度,用6*6的矩阵表示协方差,对应表示绕xyz三轴的不确定度 190 | 191 | ```cpp 192 | geometry_msgs/Pose pose 193 | float64[36] covariance 194 | ``` 195 | 196 | * geometry_msgs/PoseWithCovarianceStamped.msg 197 | 198 | 表示带有时间戳和坐标系的位姿估计 199 | 200 | ```cpp 201 | Header header 202 | PoseWithCovariance pose 203 | ``` 204 | 205 | #### Twist、TwistStamped、TwistWithCovariance、TwistWithCovarianceStamped 206 | 207 | * geometry_msgs/Twist.msg 208 | 209 | 表示自由空间的一组速度,包括线速度和角速度 210 | 211 | ```cpp 212 | geometry_msgs/Vector3 linear 213 | geometry_msgs/Vector3 angular 214 | ``` 215 | 216 | * geometry_msgs/TwistStamped.msg 217 | 218 | 表示带有时间戳和参考坐标系的速度 219 | 220 | ```cpp 221 | std_msgs/Header header 222 | geometry_msgs/Twist twist 223 | ``` 224 | 225 | * geometry_msgs/TwistWithCovariance.msg 226 | 227 | 表示带有协方差表示不确定度的速度估计 228 | 229 | ```cpp 230 | geometry_msgs/Twist twist 231 | float64[36] covariance 232 | ``` 233 | 234 | * geometry_msgs/TwistWithCovarianceStamped.msg 235 | 236 | 表示带有时间戳和参考坐标系的速度估计 237 | 238 | ```cpp 239 | std_msgs/Header header 240 | geometry_msgs/TwistWithCovariance twist 241 | ``` 242 | 243 | #### Accel、AccelStamped、AccelWithCovariance、AccelWithCovarianceStamped 244 | 245 | * geometry_msgs/Accel.msg 246 | 247 | 表示自由空间的一组加速度,包括线加速度和角加速度 248 | 249 | ```cpp 250 | geometry_msgs/Vector3 linear 251 | geometry_msgs/Vector3 angular 252 | ``` 253 | 254 | * geometry_msgs/AccelStamped.msg 255 | 256 | 表示带有时间戳和参考坐标系的加速度 257 | 258 | ```cpp 259 | std_msgs/Header header 260 | geometry_msgs/Accel accel 261 | ``` 262 | 263 | * geometry_msgs/AccelWithCovariance.msg 264 | 265 | 表示带有协方差表示不确定度的加速度估计 266 | 267 | ```cpp 268 | geometry_msgs/Accel accel 269 | float64[36] covariance 270 | ``` 271 | 272 | * geometry_msgs/AccelWithCovarianceStamped.msg 273 | 274 | 表示带有时间戳和参考坐标系的加速度估计 275 | 276 | ```cpp 277 | std_msgs/Header header 278 | geometry_msgs/AccelWithCovariance accel 279 | ``` 280 | 281 | #### Ploygon、PloygonStamped 282 | 283 | * geometry_msgs/Accel.msg 284 | 285 | 表示自由空间的一块区域,用首位相连的一组点表示 286 | 287 | ```cpp 288 | geometry_msgs/Point32[] points 289 | ``` 290 | 291 | * geometry_msgs/AccelStamped.msg 292 | 293 | 表示带有参考坐标系和时间戳的自由空间的一块区域 294 | 295 | ```cpp 296 | std_msgs/Header header 297 | geometry_msgs/Polygon polygon 298 | ``` 299 | 300 | -------------------------------------------------------------------------------- /牛客网刷题笔记/动态规划专项/背包.md: -------------------------------------------------------------------------------- 1 | # 背包 2 | 3 | ## 目录 4 | 5 | - [DP41](#DP41) 6 | - [DP42](#DP42) 7 | - [DP43](#DP43) 8 | - [DP44](#DP44) 9 | - [DP45](#DP45) 10 | - [DP46](#DP46) 11 | 12 | 13 | 14 | ### DP41 15 | * DP41 01背包 16 | 17 | 描述 18 | ``` 19 | 描述 20 | 你有一个背包,最多能容纳的体积是V。 21 | 现在有n个物品,第i个物品的体积为vi ,价值为wi 。 22 | (1)求这个背包至多能装多大价值的物品? 23 | (2)若背包恰好装满,求至多能装多大价值的物品? 24 | 输入描述: 25 | 第一行两个整数n和V,表示物品个数和背包体积。 26 | 接下来n行,每行两个数vi 和wi ,表示第i个物品的体积和价值。 27 | 28 | 1≤n,V,vi ,wi ≤1000 29 | 输出描述: 30 | 输出有两行,第一行输出第一问的答案,第二行输出第二问的答案,如果无解请输出0。 31 | ``` 32 | 33 | ```cpp 34 | #include 35 | using namespace std; 36 | int main(){ 37 | int n,V; 38 | cin>>n>>V; 39 | int w[n],v[n]; 40 | for(int i=0;i>w[i]>>v[i]; 42 | } 43 | vectordp1(V+1,0); 44 | vectordp2(V+1,INT_MIN); 45 | dp2[0]=0; 46 | for(int i=0;i=w[i];j--){ 48 | dp1[j] = max(dp1[j], dp1[j - w[i]] + v[i]); 49 | dp2[j] = max(dp2[j], dp2[j - w[i]] + v[i]); 50 | 51 | } 52 | } 53 | cout< 60 | ↥ Back To Top 61 | 62 | 63 | 64 | ### DP42 65 | * DP42 完全背包 66 | 67 | 描述 68 | ``` 69 | 你有一个背包,最多能容纳的体积是V。 70 | 现在有n种物品,每种物品有任意多个,第i种物品的体积为vi ,价值为wi 。 71 | (1)求这个背包至多能装多大价值的物品? 72 | (2)若背包恰好装满,求至多能装多大价值的物品? 73 | 输入描述: 74 | 第一行两个整数n和V,表示物品个数和背包体积。 75 | 接下来n行,每行两个数vi 和wi ,表示第i种物品的体积和价值。 76 | 1≤n,V≤1000 77 | 输出描述: 78 | 输出有两行,第一行输出第一问的答案,第二行输出第二问的答案,如果无解请输出0。 79 | ``` 80 | 81 | ```cpp 82 | #include 83 | using namespace std; 84 | int main(){ 85 | int n,V; 86 | cin>>n>>V; 87 | int w[n],v[n]; 88 | for(int i=0;i>w[i]>>v[i]; 90 | } 91 | vectordp1(V+1,0); 92 | vectordp2(V+1,INT_MIN); 93 | dp2[0]=0; 94 | for(int i=0;i 108 | ↥ Back To Top 109 | 110 | 111 | 112 | ### DP43 113 | * DP43 最少的完全平方数 114 | 115 | 描述 116 | ``` 117 | 给定一个正整数n,请找出最少个数的完全平方数,使得这些完全平方数的和等于n。 118 | 完全平方指用一个整数乘以自己例如1*1,2*2,3*3等,依此类推。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。 119 | 例如:1,4,9,和16都是完全平方数,但是2,3,5,8,11等等不是 120 | 数据范围:1≤n≤10^4 ​ 121 | 输入描述: 122 | 仅一行,输入一个正整数 n 123 | 输出描述: 124 | 按题目要求输出完全平方数之和为n的最少个数 125 | ``` 126 | 127 | ```cpp 128 | #include 129 | using namespace std; 130 | int main(){ 131 | int n; 132 | cin>>n; 133 | int w[n],v[n]; 134 | for(int i=0;i>w[i]>>v[i]; 136 | } 137 | vectordp(n+1,0); 138 | for(int i = 1; i <= n; ++i){ 139 | dp[i] = i; 140 | } 141 | for(int i=2;i<=(int)sqrt(n);i++){ 142 | for(int j=0;j<=n-i*i;j++){ 143 | dp[j+i*i] = min(dp[j+i*i], dp[j ] + 1); 144 | } 145 | } 146 | cout< 152 | ↥ Back To Top 153 | 154 | 155 | 156 | ### DP44 157 | * DP44 兑换零钱 158 | 159 | 描述 160 | ``` 161 | 给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张, 162 | 再给定一个aim,代表要找的钱数,求组成aim的最少货币数。 163 | 如果无解,请返回-1. 164 | 数据范围:数组大小满足 0≤n≤10000 , 数组中每个数字都满足 0 173 | ```cpp 174 | #include 175 | using namespace std; 176 | 177 | int main() 178 | { 179 | int n, sum=0; 180 | cin >> n ; 181 | vector v(n,0); 182 | for (int i = 0; i < n; i++) { 183 | cin >> v[i]; 184 | sum+=v[i]; 185 | } 186 | if(sum&1)//奇数 187 | { 188 | cout<<"false"< dp(target+1,0); 193 | 194 | for (int i = 0; i < n; i++) { 195 | for (int j = target; j >= v[i]; j--) { 196 | dp[j]=max(dp[j],dp[j-v[i]]+v[i]); 197 | } 198 | } 199 | if(dp[target]==target) cout<<"true"< 206 | ↥ Back To Top 207 | 208 | 209 | 210 | ### DP46 211 | * DP1 dosomething 212 | 213 | 描述 214 | ``` 215 | 有一个箱子容量为 V ,同时有n个物品,每个物品有一个体积(正整数)。每个物品只能使用一次。 216 | 要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。 217 | 数据范围: 1≤V≤2×10^4,1≤n≤30 ,每个物品的体积满足 1≤num ≤2×10^4 218 | 219 | 输入描述: 220 | 第一行输入一个正整数 V 表示箱子的容量, 221 | 第二行输入一个正整数 n 表示物品的个数。 222 | 后续 n 行每行输入一个正整数表示物品的体积 223 | 输出描述: 224 | 输出箱子最小剩余空间 225 | ``` 226 | 227 | ```cpp 228 | #include 229 | using namespace std; 230 | 231 | int main() 232 | { 233 | int V, n; 234 | cin >>V>> n ; 235 | vector v(n,0); 236 | for (int i = 0; i < n; i++) { 237 | cin >> v[i]; 238 | } 239 | vector dp(V+1,0); 240 | 241 | for (int i = 0; i < n; i++) { 242 | for (int j = V; j >= v[i]; j--) { 243 | dp[j]=max(dp[j],dp[j-v[i]]+v[i]); 244 | } 245 | } 246 | cout< 252 | ↥ Back To Top 253 | 254 | 255 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/哈希.md: -------------------------------------------------------------------------------- 1 | # 哈希 2 | 3 | ## 目录 4 | 5 | - [BM50](#BM50) 6 | - [BM51](#BM51) 7 | - [BM52](#BM52) 8 | - [BM53](#BM53) 9 | - [BM54](#BM54) 10 | 11 | 12 | 13 | ## BM50 14 | * BM50 两数之和 15 | 16 | 描述 17 | ``` 18 | 给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。 19 | (注:返回的数组下标从1开始算起,保证target一定可以由数组里面2个数字相加得到) 20 | 21 | 数据范围:2\leq len(numbers) \leq 10^52≤len(numbers)≤10 22 | 5 23 | ,-10 \leq numbers_i \leq 10^9−10≤numbers 24 | i 25 | ​ 26 | ≤10 27 | 9 28 | ,0 \leq target \leq 10^90≤target≤10 29 | 9 30 | 31 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(nlogn)O(nlogn) 32 | ``` 33 | 34 | ```cpp 35 | class Solution { 36 | public: 37 | /** 38 | * 39 | * @param numbers int整型vector 40 | * @param target int整型 41 | * @return int整型vector 42 | */ 43 | vector twoSum(vector& numbers, int target) { 44 | // write code here 45 | unordered_map m; 46 | for(int i = 0; i 58 | ↥ Back To Top 59 | 60 | 61 | 62 | ## BM51 63 | * BM51 数组中出现次数超过一半的数字 64 | 65 | 描述 66 | ``` 67 | 给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 68 | 例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。 69 | 70 | 数据范围:n \le 50000n≤50000,数组中元素的值 0 \le val \le 100000≤val≤10000 71 | 要求:空间复杂度:O(1)O(1),时间复杂度 O(n)O(n) 72 | ``` 73 | 74 | ```cpp 75 | class Solution { 76 | public: 77 | int MoreThanHalfNum_Solution(vector numbers) { 78 | //无序哈希表统计每个数字出现的次数 fast-template 79 | unordered_map mp; 80 | //遍历数组 81 | for(int i = 0; i < numbers.size(); i++){ 82 | //哈希表中相应数字个数加1 83 | mp[numbers[i]]++; 84 | //一旦有个数大于长度一半的情况即可返回 85 | if(mp[numbers[i]] > numbers.size() / 2) 86 | return numbers[i]; 87 | } 88 | return 0; 89 | } 90 | }; 91 | ``` 92 | 93 |
94 | ↥ Back To Top 95 |
96 | 97 | 98 | ## BM52 99 | * BM52 数组中只出现一次的两个数字 100 | 101 | 描述 102 | ``` 103 | 一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 104 | 105 | 数据范围:数组长度 2\le n \le 10002≤n≤1000,数组中每个数的大小 0 < val \le 10000000 111 | ```cpp 112 | class Solution { 113 | public: 114 | /** 115 | * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 116 | * 117 | * 118 | * @param array int整型vector 119 | * @return int整型vector 120 | */ 121 | vector FindNumsAppearOnce(vector& array) { 122 | // write code here 123 | unordered_mapmp; 124 | vector res; 125 | for(int i=0;i 140 | ↥ Back To Top 141 | 142 | 143 | 144 | ## BM53 145 | * BM53 缺失的第一个正整数 146 | 147 | 描述 148 | ``` 149 | 给定一个未排序的整数数组nums,请你找出其中没有出现的最小的正整数 150 | 151 | 进阶: 空间复杂度 O(1)O(1),时间复杂度 O(n)O(n) 152 | 153 | 数据范围: 154 | -231<=nums[i]<=231-1 155 | 0<=len(nums)<=5*105 156 | ``` 157 | 158 | ```cpp 159 | class Solution { 160 | public: 161 | int minNumberDisappeared(vector& nums) { 162 | int n = nums.size(); 163 | unordered_map mp; 164 | //哈希表记录数组中出现的每个数字 fast-template 165 | for(int i = 0; i < n; i++) 166 | mp[nums[i]]++; 167 | int res = 1; 168 | //从1开始找到哈希表中第一个没有出现的正整数 169 | while(mp.find(res) != mp.end()) 170 | res++; 171 | return res; 172 | } 173 | }; 174 | ``` 175 | 176 |
177 | ↥ Back To Top 178 |
179 | 180 | 181 | ## BM54 182 | * BM54 三数之和 183 | 184 | 描述 185 | ``` 186 | 给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。 187 | 188 | 数据范围:0 \le n \le 30000≤n≤3000,数组中各个元素值满足 |val | \le 100∣val∣≤100 189 | 空间复杂度:O(n^2)O(n 190 | 2 191 | ),时间复杂度 O(n^2)O(n 192 | 2 193 | ) 194 | 195 | 注意: 196 | 三元组(a、b、c)中的元素可以按任意顺序排列。 197 | 解集中不能包含重复的三元组。 198 | ``` 199 | 200 | ```cpp 201 | class Solution { 202 | public: 203 | vector > threeSum(vector &num) { 204 | vector > res; 205 | int n = num.size(); 206 | //不够三元组 fast-template 207 | if(n < 3) 208 | return res; 209 | //排序 210 | sort(num.begin(), num.end()); 211 | for(int i = 0; i < n - 2; i++){ 212 | if(i != 0 && num[i] == num[i - 1]) 213 | continue; 214 | //后续的收尾双指针 215 | int left = i + 1; 216 | int right = n - 1; 217 | //设置当前数的负值为目标 218 | int target = -num[i]; 219 | while(left < right){ 220 | //双指针指向的二值相加为目标,则可以与num[i]组成0 221 | if(num[left] + num[right] == target){ 222 | res.push_back({num[i], num[left], num[right]}); 223 | while(left + 1 < right && num[left] == num[left + 1]) 224 | //去重 225 | left++; 226 | while(right - 1 > left && num[right] == num[right - 1]) 227 | //去重 228 | right--; 229 | //双指针向中间收缩 230 | left++; 231 | right--; 232 | } 233 | //双指针指向的二值相加大于目标,右指针向左 234 | else if(num[left] + num[right] > target) 235 | right--; 236 | //双指针指向的二值相加小于目标,左指针向右 237 | else left++; 238 | } 239 | } 240 | return res; 241 | } 242 | }; 243 | ``` 244 | 245 |
246 | ↥ Back To Top 247 |
248 | 249 | 250 | -------------------------------------------------------------------------------- /linux使用/docker.md: -------------------------------------------------------------------------------- 1 | # docker 2 | ## 目录 3 | 4 | 5 | 6 | - [安装](#安装) 7 | - [常用命令](#常用命令) 8 | - [挂载文件](#挂载文件) 9 | - [提交镜像](#提交镜像) 10 | - [dockerfile](#dockerfile) 11 | 12 | 13 | 14 | ## 安装 15 | 16 | - [官方教程](https://docs.docker.com/engine/install/ubuntu/) 17 | 18 | 19 | 1. 卸载旧版本docker 20 | 21 | ```shell 22 | sudo apt-get remove docker docker-engine docker.io containerd runc 23 | ``` 24 | 25 | 26 | 27 | 28 | 2. 更新及安装工具软件 29 | 30 | ```shell 31 | sudo apt-get update 32 | ``` 33 | 34 | ```shell 35 | sudo apt-get install \ 36 | apt-transport-https \ 37 | ca-certificates \ 38 | curl \ 39 | gnupg \ 40 | lsb-release 41 | ``` 42 | 43 | ```shell 44 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg 45 | 46 | ``` 47 | 48 | ```shell 49 | echo \ 50 | "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ 51 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 52 | ``` 53 | 54 | 55 | 56 | 57 | 58 | 59 | 3. 安装docker 60 | 61 | ```shell 62 | sudo apt-get update 63 | ``` 64 | 65 | ```shell 66 | sudo apt-get install docker-ce docker-ce-cli containerd.io -y 67 | 68 | ``` 69 | 70 | 71 | 72 | 73 | 4. 查看是否启动docker 74 | 75 | ```shell 76 | ps aux|grep docker 77 | ``` 78 | 79 | 80 | 81 | 82 | 5. 测试运行一个docker容器 83 | 84 | ```shell 85 | sudo docker run hello-world 86 | ``` 87 | 88 | 89 | 90 |
91 | ↥ Back To Top 92 |
93 | 94 | ## 常用命令 95 | 96 | [常用命令](https://blog.csdn.net/weixin_45698637/article/details/124213429?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167930369916800182761750%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167930369916800182761750&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-124213429-null-null.142^v74^insert_down2,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=docker%E5%90%AF%E5%8A%A8%E5%AE%B9%E5%99%A8%E5%91%BD%E4%BB%A4&spm=1018.2226.3001.4187) 97 | 98 | * 启动docker 99 | 100 | ```bash 101 | systemctl start docker 102 | ``` 103 | * 关闭docker 104 | 105 | ```bash 106 | systemctl stop docker 107 | ``` 108 | * 重启docker 109 | 110 | ```bash 111 | systemctl restart docker 112 | ``` 113 | * docker设置随服务启动而自启动 114 | 115 | ```bash 116 | systemctl enable docker 117 | ``` 118 | * 查看docker 运行状态 119 | 120 | ```bash 121 | systemctl status docker 122 | ``` 123 | * 查看docker 版本号信息 124 | 125 | ```bash 126 | docker version 127 | docker info 128 | ``` 129 | * docker帮助命令 130 | 131 | ```bash 132 | docker --help 133 | docker pull --help #docker 命令 --help 134 | ``` 135 | * 查看自己服务器中docker 镜像列表 136 | 137 | ```bash 138 | docker images 139 | ``` 140 | * 搜索镜像 141 | 142 | ```bash 143 | docker search mysql 144 | docker search --filter=STARS=9000 mysql 145 | ``` 146 | * 拉取镜像 147 | 148 | ```bash 149 | docker pull mysql 150 | docker pull mysql:5.7.30 #docker pull 镜像名:tag 151 | ``` 152 | * 运行镜像 153 | 154 | ```bash 155 | docker run tomcat 156 | docker run mysql:5.7.30 #docker run 镜像名:Tag 157 | ``` 158 | * 删除镜像 159 | 160 | ```bash 161 | docker rmi -f mysql #docker rmi -f 镜像名/镜像ID 162 | docker rmi -f mysql tomcat #删除多个 163 | docker rmi -f $(docker images -aq) #删除全部 164 | ``` 165 | * 启动docker 166 | 167 | ```bash 168 | systemctl start docker 169 | ``` 170 | 171 | * 强制删除镜像 172 | 173 | ```bash 174 | docker image rm 镜像名称/镜像ID 175 | ``` 176 | 177 | * 保存镜像 178 | 179 | ```bash 180 | docker save tomcat -o /myimg.tar 181 | ``` 182 | 183 | * 加载镜像 184 | 185 | ```bash 186 | docker load -i myimg.tar 187 | ``` 188 | 189 | 190 | * 查看正在运行容器列表 191 | 192 | ```bash 193 | docker ps 194 | ``` 195 | 196 | 197 | * 查看所有容器 198 | 199 | ```bash 200 | docker ps -a 201 | ``` 202 | 203 | 204 | * 运行一个容器 205 | 206 | ```bash 207 | docker run -it -d --name 要取的别名 镜像名:Tag /bin/bash 208 | docker run -it -d --name redis001 redis:5.0.5 /bin/bash 209 | ``` 210 | 211 | 212 | * 停止容器 213 | 214 | ```bash 215 | docker stop 容器名/容器ID 216 | docker stop redis001 217 | ``` 218 | 219 | * 删除容器 220 | 221 | ```bash 222 | #删除一个容器 223 | docker rm -f 容器名/容器ID 224 | #删除多个容器 空格隔开要删除的容器名或容器ID 225 | docker rm -f 容器名/容器ID 容器名/容器ID 容器名/容器ID 226 | #删除全部容器 227 | docker rm -f $(docker ps -aq) 228 | ``` 229 | 230 | * 容器端口与服务器端口映射 231 | 232 | ```bash 233 | -p 宿主机端口:容器端口 234 | docker run -itd --name redis002 -p 8888:6379 redis:5.0.5 /bin/bash 235 | ``` 236 | 237 | * 进入容器 238 | 239 | ```bash 240 | docker exec -it 容器名/容器ID /bin/bash 241 | 242 | #进入 前面的 redis001容器 243 | docker exec -it redis001 /bin/bash 244 | docker attach 容器名/容器ID 245 | ``` 246 | 247 | * 复制文件到容器 248 | 249 | ``` 250 | docker cp 你的文件路径 容器长ID:docker容器路径 251 | sudo docker cp LIO-SAM.zip 0ee1df0e92f3:LIO.zip 252 | ``` 253 | * 退出容器 254 | 255 | ```bash 256 | #-----直接退出 未添加 -d(持久化运行容器) 时 执行此参数 容器会被关闭 257 | exit 258 | # 优雅退出 --- 无论是否添加-d 参数 执行此命令容器都不会被关闭 259 | Ctrl + p + q 260 | ``` 261 | * kill容器 262 | 263 | ```bash 264 | docker kill 容器ID/容器名 265 | ``` 266 | * 容器文件拷贝 267 | 268 | ```bash 269 | #docker cp 容器ID/名称:文件路径 要拷贝到外部的路径 | 要拷贝到外部的路径 容器ID/名称:文件路径 270 | #从容器内 拷出 271 | docker cp 容器ID/名称: 容器内路径 容器外路径 272 | #从外部 拷贝文件到容器内 273 | docker cp 容器外路径 容器ID/名称: 容器内路径 274 | ``` 275 | * 查看容器日志 276 | 277 | ```bash 278 | docker logs -f --tail=要查看末尾多少行 默认all 容器ID 279 | ``` 280 | * 容器随docker服务启动而自动启动--restart=always 281 | 282 | ```bash 283 | docker run -itd --name redis002 -p 8888:6379 --restart=always redis:5.0.5 /bin/bash 284 | ``` 285 | 286 | 287 | 288 |
289 | ↥ Back To Top 290 |
291 | 292 | ## 挂载文件 293 | 294 | * 命令 295 | 296 | ```bash 297 | -v 宿主机文件存储位置:容器内文件位置 298 | -v 宿主机文件存储位置:容器内文件位置 -v 宿主机文件存储位置:容器内文件位置 -v 宿主机文件存储位置:容器内文件位置 299 | # 运行一个docker redis 容器 进行 端口映射 两个数据卷挂载 设置开机自启动 300 | docker run -d -p 6379:6379 --name redis505 --restart=always -v /var/lib/redis/data/:/data -v /var/lib/redis/conf/:/usr/local/etc/redis/redis.conf redis:5.0.5 --requirepass "password" 301 | 302 | ``` 303 | 304 | 305 | 306 |
307 | ↥ Back To Top 308 |
309 | ## 提交镜像 310 | * 提交自己的镜像 311 | 312 | ```bash 313 | docker commit -m="提交信息" -a="作者信息" 容器名/容器ID 提交后的镜像名:Tag 314 | ``` 315 | 316 | 317 | 318 | 319 | 320 | 321 |
322 | ↥ Back To Top 323 |
324 | ## dockerfile 325 | 326 | 327 | 328 | 329 | 330 |
331 | ↥ Back To Top 332 |
333 | -------------------------------------------------------------------------------- /learnCpp/面经.md: -------------------------------------------------------------------------------- 1 | ## 面经分享 2 | ## 找工作是真的难 3 |
4 | 5 |
6 | 7 | * [笔试总结](牛客网刷题笔记/笔试总结.md) 8 | 有些公司喜欢问八股文,总结的word在这里,自行下载。 9 | * [八股文总结](https://docs.google.com/document/d/17r0LKghSM_9Eom2j8PJkyRhCHTKZoG89/edit?usp=sharing&ouid=100339261727029428476&rtpof=true&sd=true) 10 | 11 | 16 | 17 | ## 目录 18 | - [公司官网](https://docs.qq.com/sheet/DZGFhVXpxdXViSVZC?tab=BB08J2&u=664f877c73e74560b8e309ae0920a36a) 19 | - [智力题总结](牛客网刷题笔记/智力题总结.md) 20 | - [李某](#李某) 21 | - [杜凯](#杜凯) 22 | - [李金洋](#李金洋) 23 | - [才昌照](#才昌照) 24 | - [周林峰](#周林峰) 25 | - [王轶](#王轶) 26 | 27 | ## 反问环节 28 |
29 | 点击查看 30 | 31 | ``` 32 | 首先分为技术面试官和HR两个角色出发: 33 | 34 | 反问技术面试官,可以问: 35 | 36 | 1、自己所应聘的部门有多少人?进去后是由谁负责带? 37 | 基本上根据这个部门员工的人数,你就可以大致了解他们的实力和规模,甚至是预测出他们这个部门目前处于一个什么样的水平和状态。 38 | 2、贵公司就前端而言所用到的技术栈? 39 | 看自己掌握的技术是否与公司所用的技术是否匹配,并且可以看出自己与工作中所需要技能的差距。 40 | 3、贵公司的培训项目是什么样的呢? 41 | 4、这次面试多久可以出结果?是否还有下一轮? 42 | 5、学习建议类 43 | (如果面试的时候对自己的技术面很没底的话,这个时候你可以问一问别人关于学习前端的一些经验,一般面试官都很乐于告诉你的) 44 | 6、您希望我们实习生身上具有什么样的特质呢? 45 | (这个是看令人心动的offer上get到的问题,个人觉得很好) 46 | 7、您面试到现在,看了这么多候选人,您觉得我相对于这个岗位,还有哪些差距需要改善? 47 | 48 | 反问HR,可以问: 49 | 50 | 1、公司的公司氛围、团队建设是怎样子的? 51 | 2、这个岗位出差、加班多吗? 52 | 3、新人有培训吗? 53 | 4、公司的晋升机制是什么样子的呢? 54 | 5、公司有餐补、房补、交通补助之类的吗? 55 | 6、当面试官问你的薪资要求时,你可以先问一下公司的薪酬体系 56 | 7、您认为考核这个岗位员工的最重要指标有哪些? 57 | 8、您觉得这个团队的氛围怎么样? 58 | ``` 59 |
60 | 61 | 62 | ## 李某 63 | 64 | 65 | ### tplink 66 |
67 | 点击查看 68 | 69 | * 笔试 70 | 71 | 72 | ``` 73 | 1.内存越界 74 | 2.最大连续子数组乘积 75 | 3.链表中环的入口 76 | 77 | ``` 78 | 79 | * 一面 80 | 81 | 82 | ``` 83 | 1.排序算法有哪些 84 | 2.快排的原理和时间复杂度 85 | 3.平衡二叉树 86 | 4.中序遍历 87 | 5.先序、中序、后序遍历的应用场合 88 | 6.对多态的理解 89 | 7.两个栈实现一个队列 90 | 8.TCP是什么,是否是可靠传输,如何保证可靠传输 91 | 9.如何实现拥塞控制 92 | 93 | 94 | ``` 95 | 96 | * 二面 97 | ``` 98 | 自我介绍 99 | 面试官你好,我是李琦,来自四川达州。 100 | 就读于电子科技大学机器人研究中心,目前 101 | 研二,研究方向是视觉SLAM,就是基于视觉 102 | 的机器人同时定位与建图算法。平时主要使用的 103 | 语言是C++,对linux操作系统和机器人操作系统 104 | Ros都很熟悉。我的项目经历主要开发扫地机器人 105 | 的带回环检测功能的同时定位与建图算法。主要负责 106 | 给系统移植回环检测模块,传感器的标定(包括相机 107 | 的标定,IMU的标定,相机和IMU的联合标定)。 108 | 以及解决算法在实际应用场景中由于特征稀疏,光照变化, 109 | 算力限制等带来的问题。 110 | 在竞赛方面,我参加了电子科技大学和长虹联合实验室 111 | 举办的扫地机器人创新方案设计比赛,获得一等奖,被 112 | 长虹公司采纳,预计很快该方案的产品就会在市场上 113 | 销售。我还参加了今年的华为软件精英挑战赛,担任队长, 114 | 获得成渝赛区32强,并在复赛中获得15名,初赛和复赛的 115 | 代码都开源在github。还参加了中兴举办的中兴捧月算法 116 | 个人赛,成功进入复赛,两个阶段的代码也开源在github 117 | 上面。 118 | 我的自我评价就是,喜欢钻研技术和分享技术。 119 | 120 | 项目相关 121 | 122 | 1.若干根非均匀的绳子,每根绳子烧完的时间是1个小时。如何得到15分钟的时间? 123 | 一根绳子两端点燃得到30分钟,另一根绳子先点燃,然后在30分钟时点燃另一端,得到15分钟。 124 | 2.进程的状态,各个状态之间的转换及条件。 125 | 3.浏览器输入网址后,发生的全过程和各种协议(DNS,TCP,HTTP) 126 | 4.安全的http(https),HTTPS是计算机网络进行安全通信的传输协议,加密(SSL) 127 | 5.对哈希表的理解,避免冲突的算法有哪些。 128 | 6.malloc,以及使用后是否立即分配内存。 129 | 7.用户态和内核态 130 | 131 | 132 | ``` 133 | 134 | 135 | * 三面 136 | 137 | 138 | ``` 139 | 没有自我介绍 140 | 问一些项目相关的问题 141 | 问我有什么想问的 142 | 143 | 144 | ``` 145 | 146 | * 座谈会 147 | 148 | 149 | ``` 150 | 试用期4个月 90%薪资 151 | 四个月年终奖 152 | 第一年年终奖根据转正后折算 153 | 社保 154 | 深圳 一档(深圳户口10%) 二档(8%) 公司25% 155 | 成都 个人10% 公司25% 156 | 157 | 158 | 公积金 159 | 各人和公司各5%(成都交在高新区) 160 | 161 | 工作时间和休假 162 | 163 | ``` 164 |
165 | 166 | ### 哲库 167 | 168 |
169 | 点击查看 170 | 171 | * 一面 172 | 173 | ``` 174 | 先自我介绍 175 | 然后问项目 176 | 然后c++相关 177 | 178 | 1.多态 179 | 2.虚拟地址和物理地址 180 | 3.用户态和内核态 181 | 4.进程间通信 182 | 5.虚函数和纯虚函数 183 | 6.各种排序算法和时间复杂度 184 | 7.智能指针有哪些,并介绍 185 | 8.指针和引用的区别 186 | 9.别名的几种方式(引用,#define typedef using) 187 | 188 | 编程: 189 | 1.二叉树的最小深度 190 | 2.最长连续序列 191 | ``` 192 | 193 |
194 |
195 | ↥ Back To Top 196 |
197 | 198 | 199 | 200 | ## 杜凯 201 | 202 | ### tplink 203 | 204 |
205 | 点击查看 206 | 207 | * 二面 208 | 209 | ``` 210 | 1.项目相关 硬件怎样实现,软硬件平台 211 | 212 | 2.全局变量和局部变量的区别及应用场景 213 | 214 | 3.tcp和udp的区别 215 | 216 | 4.堆和栈是什么,那些数据用到了堆和栈,malloc用到了堆还是栈? 217 | 218 | 5.链表和数组有哪些区别,哪些数据用到了,应用场景 219 | 220 | 6.走100级阶梯有多少种走法,实现方式,我说了用递归实现,他又问如果走1000级, 221 | 10000级还能用递归实现吗,考虑到递归可能爆内存我说了要不用动态规划来做吧, 222 | 然后他就又问为什么不用递归,有哪些缺点。 223 | ``` 224 | 225 | * 三面 226 | 227 | ``` 228 | 1.项目相关,展开将 229 | 230 | 2.成绩 231 | 232 | 3.数组和链表异同 233 | 234 | 4.投软件开发嵌入式方向岗位,有准备学习什么内容码? 235 | 236 | 5.兴趣爱好 237 | ``` 238 |
239 | 240 | ### 字节 241 | 242 |
243 | 点击查看 244 | 245 | * 一面 246 | 247 | ``` 248 | 1.项目相关,问的挺久挺深的,细节描述一个项目 249 | 2.过拟合和欠拟合,概念(因为我开始把这两个概念说错了,后来纠正回来),数据量和模型参数的关 250 | 系,怎样才能有最佳的训练效果 251 | 3.避免过拟合的方式:正则化,数据增强,dropout 252 | 4.dropout的作用及原理,为什么能有避免过拟合作用;对于训练过程和预测过程,dropout的问题有哪些, 253 | dropout的随机节点选取会不会导致预测结果的随机性,如果会的话,怎样解决?如果预测过程去掉 254 | dropout,会对预测结果有哪些影响?答案从影响数据分布的角度出发。 255 | 5.评价指标的计算。公式我有些忘了,没答好,会给具体的数据示例让你算,没算出来。指标如, 256 | presion,recall,f1,为什么会有f1 这个指标。各个指标具体怎么算。除了这些指标还有哪些指标。AUC 和roc 257 | 曲线,我说了我觉得这两个指标不适用我的场景,他让我了解一下这两个指标的适用场景。 258 | 6.损失函数有哪些,公式写一下。我说了交叉熵和mse,写了交叉熵的公式。 259 | 7.数组和链表的区别,以及为什么会有这些区别。 260 | 8.python的gil锁,以及多进程和多线程的区别及适用场景 261 | 9.算法题:【1,3,5】,【2,4,6】有序数组合并 262 | ``` 263 | 264 | 265 |
266 |
267 | ↥ Back To Top 268 |
269 | 270 | 271 | 272 | ## 李金洋 273 | 274 | ### tplink 275 | 276 |
277 | 点击查看 278 | 279 | * 一面 280 | 281 | ``` 282 | 1.散列表 283 | 2.死锁 284 | 3.进程间通信 285 | 4.TCP,UDP 286 | 5.虚函数 287 | 6.引用和指针 288 | 289 | ``` 290 | 291 | * 二面 292 | 293 | ``` 294 | 295 | 项目相关 296 | 297 | 1.指针和引用 298 | 2.哈希表 299 | 3.兴趣和优缺点 300 | 301 | ``` 302 |
303 | 304 |
305 | ↥ Back To Top 306 |
307 | 308 | 309 | ## 才昌照 310 | 311 | ### 28所 312 |
313 | 点击查看 314 | 315 | * 一面(电话面试偷袭) 316 | 317 | ``` 318 | 1.介绍下自己项目,更新了什么 319 | 2.引用和指针的区别 320 | 3.浅拷贝和深拷贝 321 | 4.C++面向对象三个特性 322 | 5.介绍下封装继承多态 323 | 6.多态实现方式 324 | 7.动态链接的2种方式 325 | 8.内存分配方式 326 | 9.map底层实现 327 | 10.知道什么排序 328 | 11.堆排序简短介绍 329 | 330 | ``` 331 | 332 |
333 | 334 | 335 |
336 | ↥ Back To Top 337 |
338 | 339 | ## 周林峰 340 | 341 | ### 28所 342 | 343 |
344 | 点击查看 345 | 346 | * 一面(电话面试) 347 | 348 | ``` 349 | 350 | 1.自我介绍,说了项目之类的 351 | 2.问了工作城市意向,专业课学的什么 352 | 3.问了python有哪些数据类型(因为项目用python写的) 353 | 4.问了数据结构的东西,双向链表和链表区别,给两个双向链表,从某个节点后数据相同,找到这个相同开始的节点。 354 | 5.问了红黑树、平衡二叉树、二叉树用数组存储的话父节点和子节点的索引关系 355 | 6.栈和队列,还有他们的应用场景 356 | 7.了解哪些设计模式,他们的使用原因 357 | 8.知道哪些排序方法,说出熟悉的排序方法思路 358 | 9.冒泡排序的时间和空间复杂度,是不是稳定的 359 | 10.哪些排序是不稳定的,答了希尔排序,然后问了希尔排序怎么实现 360 | 11.线程进程区别,通信方法,线程锁,线程怎么创建的 361 | ``` 362 |
363 | 364 |
365 | ↥ Back To Top 366 |
367 | 368 | 369 | ## 王轶 370 | 371 | ### 联发科 372 | 373 |
374 | 点击查看 375 | 376 | * 一面 377 | 378 | ``` 379 | 380 | 1. 项目介绍 381 | 2. 为什么投递联发科 382 | 3. 你认为你哪个部分学的好(计算机网络等) 383 | 4. 拥塞控制详细说说 384 | 5. 里面的快恢复详细说说 385 | 6. 虚拟地址可以一样吗 386 | 7. 只知道虚拟地址怎么找到内存 387 | 8. 内存管理里面页表页目录的过程 388 | 9. 操作系统功能调用有哪些 389 | 10. 操作系统的中断过程 390 | 11. 操作系统的中断再来个中断怎么办,怎么避免 391 | 392 | ``` 393 |
394 | 395 |
396 | ↥ Back To Top 397 |
398 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/字符串.md: -------------------------------------------------------------------------------- 1 | # 字符串 2 | 3 | ## 目录 4 | 5 | 6 | - [BM83](#BM83) 7 | - [BM84](#BM84) 8 | - [BM85](#BM85) 9 | - [BM86](#BM86) 10 | 11 | 12 | 13 | ## BM83 14 | * BM83 字符串变形 15 | 16 | 描述 17 | ``` 18 | 对于一个长度为 n 字符串,我们需要对它做一些变形。 19 | 20 | 首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。 21 | 22 | 比如"Hello World"变形后就变成了"wORLD hELLO"。 23 | 24 | 数据范围: 1\le n \le 10^61≤n≤10 25 | 6 26 | , 字符串中包括大写英文字母、小写英文字母、空格。 27 | 进阶:空间复杂度 O(n)O(n) , 时间复杂度 O(n)O(n) 28 | ``` 29 | 30 | ```cpp 31 | class Solution { 32 | public: 33 | string trans(string s, int n) { 34 | if (n == 0) 35 | return s; 36 | string res; 37 | for (int i = 0; i < n; i++) { 38 | //大小写转换 fast-template 39 | if (s[i] <= 'Z' && s[i] >= 'A') 40 | res += s[i] - 'A' + 'a'; 41 | else if (s[i] >= 'a' && s[i] <= 'z') 42 | res += s[i] - 'a' + 'A'; 43 | else 44 | //空格直接复制 45 | res += s[i]; 46 | } 47 | //翻转整个字符串 48 | reverse(res.begin(), res.end()); 49 | for (int i = 0; i < n; i++) { 50 | int j = i; 51 | //以空格为界,二次翻转 52 | while (j < n && res[j] != ' ') 53 | j++; 54 | reverse(res.begin() + i, res.begin() + j); 55 | i = j; 56 | } 57 | return res; 58 | } 59 | }; 60 | ``` 61 | 62 |
63 | ↥ Back To Top 64 |
65 | 66 | ## BM84 67 | * BM84 最长公共前缀 68 | 69 | 描述 70 | ``` 71 | 给你一个大小为 n 的字符串数组 strs ,其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。 72 | 73 | 数据范围: 0 \le n \le 50000≤n≤5000, 0 \le len(strs_i) \le 50000≤len(strs 74 | i 75 | ​ 76 | )≤5000 77 | 进阶:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 78 | ``` 79 | 80 | ```cpp 81 | class Solution { 82 | public: 83 | string longestCommonPrefix(vector& strs) { 84 | int n = strs.size(); 85 | //空字符串数组 fast-template 86 | if (n == 0) 87 | return ""; 88 | //遍历第一个字符串的长度 89 | for (int i = 0; i < strs[0].length(); i++) { 90 | char temp = strs[0][i]; 91 | //遍历后续的字符串 92 | for (int j = 1; j < n; j++) 93 | //比较每个字符串该位置是否和第一个相同 94 | if (i == strs[j].length() || strs[j][i] != temp) 95 | //不相同则结束 96 | return strs[0].substr(0, i); 97 | } 98 | //后续字符串有整个字一个字符串的前缀 99 | return strs[0]; 100 | } 101 | }; 102 | ``` 103 | 104 |
105 | ↥ Back To Top 106 |
107 | 108 | ## BM85 109 | * BM85 验证IP地址 110 | 111 | 描述 112 | ``` 113 | 编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址 114 | 115 | IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1; 116 | 同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。 117 | 118 | IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。 119 | 120 | 然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。 121 | 同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。 122 | 123 | 说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。 124 | 125 | 数据范围:字符串长度满足 5 \le n \le 505≤n≤50 126 | 进阶:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 127 | ``` 128 | 129 | ```cpp 130 | class Solution { 131 | public: 132 | //将字符串从.或者:分割开 fast-template 133 | vector split(string s, string spliter) { 134 | vector res; 135 | int i; 136 | //遍历字符串查找spliter 137 | while ((i = s.find(spliter)) && i != s.npos) { 138 | //将分割的部分加入vector中 139 | res.push_back(s.substr(0, i)); 140 | s = s.substr(i + 1); 141 | } 142 | res.push_back(s); 143 | return res; 144 | } 145 | bool isIPv4 (string IP) { 146 | vector s = split(IP, "."); 147 | //IPv4必定为4组 148 | if (s.size() != 4) 149 | return false; 150 | for (int i = 0; i < s.size(); i++) { 151 | //不可缺省,有一个分割为零,说明两个点相连 152 | if (s[i].size() == 0) 153 | return false; 154 | //比较数字位数及不为零时不能有前缀零 155 | if (s[i].size() < 0 || s[i].size() > 3 || (s[i][0] == '0' && s[i].size() != 1)) 156 | return false; 157 | //遍历每个分割字符串,必须为数字 158 | for (int j = 0; j < s[i].size(); j++) 159 | if (!isdigit(s[i][j])) 160 | return false; 161 | //转化为数字比较,0-255之间 162 | int num = stoi(s[i]); 163 | if (num < 0 || num > 255) 164 | return false; 165 | } 166 | return true; 167 | } 168 | bool isIPv6 (string IP) { 169 | vector s = split(IP, ":"); 170 | //IPv6必定为8组 171 | if (s.size() != 8) 172 | return false; 173 | for (int i = 0; i < s.size(); i++) { 174 | //每个分割不能缺省,不能超过4位 175 | if (s[i].size() == 0 || s[i].size() > 4) 176 | return false; 177 | for (int j = 0; j < s[i].size(); j++) { 178 | //不能出现a-fA-F以外的大小写字符 179 | if (!(isdigit(s[i][j]) || (s[i][j] >= 'a' && s[i][j] <= 'f') || 180 | (s[i][j] >= 'A' && s[i][j] <= 'F'))) 181 | return false; 182 | } 183 | } 184 | return true; 185 | } 186 | string solve(string IP) { 187 | if (IP.size() == 0) 188 | return "Neither"; 189 | if (isIPv4(IP)) 190 | return "IPv4"; 191 | else if (isIPv6(IP)) 192 | return "IPv6"; 193 | return "Neither"; 194 | } 195 | }; 196 | ``` 197 | 198 |
199 | ↥ Back To Top 200 |
201 | 202 | ## BM86 203 | * BM86 大数加法 204 | 205 | 描述 206 | ``` 207 | 以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。 208 | 209 | 数据范围:s.length,t.length \le 100000s.length,t.length≤100000,字符串仅由'0'~‘9’构成 210 | 要求:时间复杂度 O(n)O(n) 211 | ``` 212 | 213 | ```cpp 214 | class Solution { 215 | public: 216 | string solve(string s, string t) { 217 | //若是其中一个为空,返回另一个 fast-template 218 | if (s.empty()) 219 | return t; 220 | if (t.empty()) 221 | return s; 222 | //让s为较长的,t为较短的 223 | if (s.length() < t.length()) 224 | swap(s, t); 225 | //进位标志 226 | int carry = 0; 227 | //从后往前遍历较长的字符串 228 | for (int i = s.length() - 1; i >= 0; i--) { 229 | //转数字加上进位 230 | int temp = s[i] - '0' + carry; 231 | //转较短的字符串相应的从后往前的下标 232 | int j = i - s.length() + t.length(); 233 | //如果较短字符串还有 234 | if (j >= 0) 235 | //转数组相加 236 | temp += t[j] - '0'; 237 | //取进位 238 | carry = temp / 10; 239 | //去十位 240 | temp = temp % 10; 241 | //修改结果 242 | s[i] = temp + '0'; 243 | } 244 | //最后的进位 245 | if (carry == 1) 246 | s = '1' + s; 247 | return s; 248 | } 249 | }; 250 | ``` 251 | 252 |
253 | ↥ Back To Top 254 |
255 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/模拟.md: -------------------------------------------------------------------------------- 1 | # 模拟 2 | 3 | ## 目录 4 | 5 | 6 | - [BM97](#BM97) 7 | - [BM98](#BM98) 8 | - [BM99](#BM99) 9 | - [BM100](#BM100) 10 | - [BM101](#BM101) 11 | 12 | 13 | ## BM97 14 | * BM97 旋转数组 15 | 16 | 描述 17 | ``` 18 | 一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,即将A中的数据由(A0 A1 ……AN-1 )变换为(AN-M …… AN-1 A0 A1 ……AN-M-1 )(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法? 19 | 20 | 数据范围:0 < n \le 1000 24 | ```cpp 25 | class Solution { 26 | public: 27 | /** 28 | * 旋转数组 29 | * @param n int整型 数组长度 30 | * @param m int整型 右移距离 31 | * @param a int整型vector 给定数组 32 | * @return int整型vector 33 | */ 34 | vector solve(int n, int m, vector& a) { 35 | // write code here 36 | m = m%n; 37 | reverse(a.begin(), a.end()); 38 | reverse(a.begin(),a.begin()+m); 39 | reverse(a.begin()+m,a.end()); 40 | return a; 41 | } 42 | }; 43 | ``` 44 | 45 |
46 | ↥ Back To Top 47 |
48 | 49 | 50 | ## BM98 51 | * BM98 螺旋矩阵 52 | 53 | 描述 54 | ``` 55 | 给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。 56 | 57 | 数据范围:0 \le n,m \le 100≤n,m≤10,矩阵中任意元素都满足 |val| \le 100∣val∣≤100 58 | 要求:空间复杂度 O(nm)O(nm) ,时间复杂度 O(nm)O(nm) 59 | ``` 60 | 61 | ```cpp 62 | class Solution { 63 | public: 64 | vector spiralOrder(vector >& matrix) { 65 | vector res; 66 | int n = matrix.size(); 67 | //先排除特殊情况 fast-template 68 | if (n == 0) 69 | return res; 70 | //左边界 71 | int left = 0; 72 | //右边界 73 | int right = matrix[0].size() - 1; 74 | //上边界 75 | int up = 0; 76 | //下边界 77 | int down = n - 1; 78 | //直到边界重合 79 | while (left <= right && up <= down) { 80 | //上边界的从左到右 81 | for (int i = left; i <= right; i++) 82 | res.push_back(matrix[up][i]); 83 | //上边界向下 84 | up++; 85 | if (up > down) 86 | break; 87 | //右边界的从上到下 88 | for (int i = up; i <= down; i++) 89 | res.push_back(matrix[i][right]); 90 | //右边界向左 91 | right--; 92 | if (left > right) 93 | break; 94 | //下边界的从右到左 95 | for (int i = right; i >= left; i--) 96 | res.push_back(matrix[down][i]); 97 | //下边界向上 98 | down--; 99 | if (up > down) 100 | break; 101 | //左边界的从下到上 102 | for (int i = down; i >= up; i--) 103 | res.push_back(matrix[i][left]); 104 | //左边界向右 105 | left++; 106 | if (left > right) 107 | break; 108 | } 109 | return res; 110 | } 111 | }; 112 | ``` 113 | 114 |
115 | ↥ Back To Top 116 |
117 | 118 | 119 | ## BM99 120 | * BM99 顺时针旋转矩阵 121 | 122 | 描述 123 | ``` 124 | 有一个nxn整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。 125 | 126 | 给定一个nxn的矩阵,和矩阵的阶数n,请返回旋转后的nxn矩阵。 127 | 128 | 数据范围:0 < n < 3000 140 | ```cpp 141 | class Solution { 142 | public: 143 | vector > rotateMatrix(vector > mat, int n) { 144 | //矩阵转置 fast-template 145 | for(int i = 0; i < n; i++) 146 | for(int j = 0; j < i; j++) 147 | //交换上三角与下三角对应的元素 148 | swap(mat[i][j], mat[j][i]); 149 | //每行翻转 150 | for(int i = 0; i < n; i++) 151 | reverse(mat[i].begin(), mat[i].end()); 152 | return mat; 153 | } 154 | }; 155 | ``` 156 | 157 |
158 | ↥ Back To Top 159 |
160 | 161 | 162 | ## BM100 163 | * BM100 设计LRU缓存结构 164 | 165 | 描述 166 | ``` 167 | 设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 capacity ,操作次数是 n ,并有如下功能: 168 | 1. Solution(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存 169 | 2. get(key):如果关键字 key 存在于缓存中,则返回key对应的value值,否则返回 -1 。 170 | 3. set(key, value):将记录(key, value)插入该结构,如果关键字 key 已经存在,则变更其数据值 value,如果不存在,则向缓存中插入该组 key-value ,如果key-value的数量超过capacity,弹出最久未使用的key-value 171 | 172 | 提示: 173 | 1.某个key的set或get操作一旦发生,则认为这个key的记录成了最常使用的,然后都会刷新缓存。 174 | 2.当缓存的大小超过capacity时,移除最不经常使用的记录。 175 | 3.返回的value都以字符串形式表达,如果是set,则会输出"null"来表示(不需要用户返回,系统会自动输出),方便观察 176 | 4.函数set和get必须以O(1)的方式运行 177 | 5.为了方便区分缓存里key与value,下面说明的缓存里key用""号包裹 178 | 数据范围: 179 | 1\leq capacity<=10^51≤capacity<=10 180 | 5 181 | 182 | 0\leq key,val \leq 2\times 10^9 \0≤key,val≤2×10 183 | 9 184 | 185 | 1\leq n\leq 10^51≤n≤10 186 | 5 187 | 188 | ``` 189 | 190 | ```cpp 191 | 192 | ``` 193 | 194 |
195 | ↥ Back To Top 196 |
197 | 198 | 199 | ## BM101 200 | * BM101 设计LFU缓存结构 201 | 202 | 描述 203 | ``` 204 | 一个缓存结构需要实现如下功能。 205 | set(key, value):将记录(key, value)插入该结构 206 | get(key):返回key对应的value值 207 | 但是缓存结构中最多放K条记录,如果新的第K+1条记录要加入,就需要根据策略删掉一条记录,然后才能把新记录加入。这个策略为:在缓存结构的K条记录中,哪一个key从进入缓存结构的时刻开始,被调用set或者get的次数最少,就删掉这个key的记录; 208 | 如果调用次数最少的key有多个,上次调用发生最早的key被删除 209 | 这就是LFU缓存替换算法。实现这个结构,K作为参数给出 210 | 211 | 数据范围:0 < k \le 10^50 225 | ```cpp 226 | class Solution { 227 | public: 228 | //用list模拟双向链表,双向链表中数组第0位为频率,第1位为key,第2位为val fast-template 229 | //频率到双向链表的哈希表 230 | unordered_map > > freq_mp; 231 | //key到双向链表节点的哈希表 232 | unordered_map > ::iterator> mp; 233 | //记录当前最小频次 234 | int min_freq = 0; 235 | //记录缓存剩余容量 236 | int size = 0; 237 | vector LFU(vector >& operators, int k) { 238 | //记录输出 239 | vector res; 240 | size = k; 241 | //遍历所有操作 242 | for(int i = 0; i < operators.size(); i++){ 243 | auto op = operators[i]; 244 | if(op[0] == 1) 245 | //set操作 246 | set(op[1], op[2]); 247 | else 248 | //get操作 249 | res.push_back(get(op[1])); 250 | } 251 | return res; 252 | } 253 | //调用函数时更新频率或者val值 254 | void update(list >::iterator iter, int key, int value) { 255 | //找到频率 256 | int freq = (*iter)[0]; 257 | //原频率中删除该节点 258 | freq_mp[freq].erase(iter); 259 | //哈希表中该频率已无节点,直接删除 260 | if(freq_mp[freq].empty()){ 261 | freq_mp.erase(freq); 262 | //若当前频率为最小,最小频率加1 263 | if(min_freq == freq) 264 | min_freq++; 265 | } 266 | //插入频率加一的双向链表表头,链表中对应:freq key value 267 | freq_mp[freq + 1].push_front({freq + 1, key, value}); 268 | mp[key] = freq_mp[freq + 1].begin(); 269 | } 270 | //set操作函数 271 | void set(int key, int value) { 272 | //在哈希表中找到key值 273 | auto it = mp.find(key); 274 | if(it != mp.end()) 275 | //若是哈希表中有,则更新值与频率 276 | update(it->second, key, value); 277 | else{ 278 | //哈希表中没有,即链表中没有 279 | if(size == 0){ 280 | //满容量取频率最低且最早的删掉 281 | int oldkey = freq_mp[min_freq].back()[1]; 282 | //频率哈希表中删除 283 | freq_mp[min_freq].pop_back(); 284 | if(freq_mp[min_freq].empty()) 285 | freq_mp.erase(min_freq); 286 | //链表哈希表中删除 287 | mp.erase(oldkey); 288 | } 289 | //若有空闲则直接加入,容量减1 290 | else 291 | size--; 292 | //最小频率置为1 293 | min_freq = 1; 294 | //在频率为1的双向链表表头插入该键 295 | freq_mp[1].push_front({1, key, value}); 296 | //哈希表key值指向链表中该位置 297 | mp[key] = freq_mp[1].begin(); 298 | } 299 | } 300 | //get操作函数 301 | int get(int key) { 302 | int res = -1; 303 | //查找哈希表 304 | auto it = mp.find(key); 305 | if(it != mp.end()){ 306 | auto iter = it->second; 307 | //根据哈希表直接获取值 308 | res = (*iter)[2]; 309 | //更新频率 310 | update(iter, key, res); 311 | } 312 | return res; 313 | } 314 | }; 315 | ``` 316 | 317 |
318 | ↥ Back To Top 319 |
320 | 321 | 322 | -------------------------------------------------------------------------------- /slamNotes/毕业设计.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | # 面向低纹理场景的机器人鲁棒定位方法研究 6 | 7 | 低纹理常见关键词 8 | * SLAM for Low-texture Environments 9 | * Low Texture Indoor Environments 10 | * challenging indoor scenes 11 | * nearly texture-less scenes 12 | 13 | * [低纹理数据集](https://vision.in.tum.de/data/datasets/rgbd-dataset/download#freiburg3_nostructure_notexture_far) 14 | * [low-textured dataset](http://mapir.isa.uma.es/mapirwebsite/?p=2108) 15 | * [回环检测数据集](https://github.com/z3rg/rtabmap/wiki/Benchmark) 16 | 17 | 18 | ## 四个一 19 | * 一个对标系统([OpenVins](https://docs.openvins.com/index.html)) 20 | * 一套代码([OpenVins](https://github.com/rpng/open_vins/)+[GMS](https://github.com/JiawangBian/GMS-Feature-Matcher)+[MILD](https://github.com/lhanaf/MILD)) 21 | * 一个文档([文档](https://drive.google.com/?tab=ro&authuser=0)) 22 | * 一个系统/论文(论文) 23 | 24 | ## 研究内容 25 | * 基于间接特征匹配的前端特征跟踪方法研究 26 | * 光流法改进为间接匹配方法 27 | * [ORB特征点均匀化](https://blog.csdn.net/djfjkj52/article/details/115173349) 28 | * [加入运动信息解决重复纹理误匹配](https://zhuanlan.zhihu.com/p/107032156) 29 | 30 | * 面向低纹理重复特征的回环检测研究 31 | * 多索引哈希-->贝叶斯推理 32 | * 帧内和帧间相似性抑制 33 | * [序列匹配](https://github.com/Mingrui-Yu/Seq-CALC) 34 | 35 | 36 | [点云转octomap](https://github.com/Ewenwan/octomap_mapping) 37 | [特征匹配评估](https://jwbian.net/fm-bench) 38 | 39 | ## 目录 40 | - [摘要](#摘要) 41 | - [ABSTRACT](#ABSTRACT) 42 | - [研究背景](#研究背景) 43 | - [GMS算法的改进和优化](#GMS算法的改进和优化) 44 | - [特征置信度的优化](#特征置信度的优化) 45 | - [重复纹理的回环检测](#重复纹理的回环检测) 46 | - [系统和实验](#系统和实验) 47 | - [总结和展望](#总结和展望) 48 | - [致谢](#致谢) 49 | 50 | 53 | 54 | 55 |
56 | 57 |
58 | 59 | 60 | 61 | 62 | ## 摘要 63 | ``` 64 | 论文研究内容 65 | 66 | 关键词:视觉SLAM 低纹理场景 卡尔曼滤波 简介匹配策略 重复纹理 回环检测 67 | 68 | ``` 69 | 70 | ## ABSTRACT 71 | 72 | ``` 73 | something about this paper 74 | 75 | Keywords: thing1, thing2, thing3 76 | ``` 77 | ## 研究背景 78 | 79 |
80 | ↥ Back To Top 81 |
82 | 83 | 84 | ## GMS算法的改进和优化 85 | ### 参考论文 86 | ``` 87 | [1] Geneva P, Eckenhoff K, Lee W, et al. Openvins: A research platform for visual-inertial estimation[C]//2020 IEEE International Conference on Robotics and Automation (ICRA). IEEE, 2020: 4666-4672. 88 | [2] Bian J W, Lin W Y, Matsushita Y, et al. Gms: Grid-based motion statistics for fast, ultra-robust feature correspondence[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2017: 4181-4190. 89 | ``` 90 | ### 理论推导 91 | 92 |
93 | 94 |
95 |

96 | 97 |
98 | 99 |
100 | ↥ Back To Top 101 |
102 | 103 | 104 | ## 特征置信度的优化 105 | ### 参考论文 106 | ``` 107 | 108 | ``` 109 | 110 | ### 理论推导 111 | - 方差 112 |
113 | 114 |
115 | 116 |
117 | 118 | - 协方差 119 | 120 | 121 |
122 | 123 |
124 |

125 | 126 |
127 | 128 | - 相关系数 129 | 130 |
131 | 132 |
133 | 134 |
135 | 136 | - 协方差矩阵 137 | 138 |
139 | 140 |
141 |

142 | 143 |
144 | 145 | - 信息矩阵 146 | 147 |
148 |
149 |
150 | 151 | 152 | 153 |
154 | ↥ Back To Top 155 |
156 | 157 | 158 | ## 重复纹理的回环检测 159 | 160 | 161 | * [回环检测相关论文和调研](https://blog.csdn.net/qq_40679814?type=blog) 162 | * [回环检测评估](https://github.com/nicolov/simple_slam_loop_closure) 163 | * [序列匹配](https://github.com/Mingrui-Yu/Seq-CALC) 164 | * [Detecting Loop Closure with Scene Sequences](chrome-extension://bocbaocobfecmglnmeaeppambideimao/pdf/viewer.html?file=http%3A%2F%2F192.41.170.42%2F~mdailey%2Fcvreadings%2FHo-LoopClosure.pdf) 165 | * [施密特-沃特曼算法](https://zh.m.wikipedia.org/zh-hans/%E5%8F%B2%E5%AF%86%E6%96%AF-%E6%B2%83%E7%89%B9%E6%9B%BC%E7%AE%97%E6%B3%95) 166 | 167 | 168 | ### 参考论文 169 | 170 | ``` 171 | [1] Han L, Fang L. MILD: Multi-index hashing for loop closure detection[J]. arXiv preprint arXiv:1702.08780, 2017. 172 | 173 | [2] Han L, Zhou G, Xu L, et al. Beyond SIFT using binary features in loop closure detection[C]//2017 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS). IEEE, 2017: 4057-4063. 174 | 175 | [3] Jégou H, Douze M, Schmid C. On the burstiness of visual elements[C]//2009 IEEE conference on computer vision and pattern recognition. IEEE, 2009: 1169-1176. 176 | 177 | 178 | ``` 179 | 180 | 重复纹理: 181 | * 图像内:'纹理在图片内多次出现' 182 | * 图像间:'相似的物品在多个地方重复出现' 183 | 184 | 文章揭示了图像集中存在大量多次出现的视觉元素,即重复模式。这样视觉元素会严重影响图像检索时的相似度计算,所以需要除去burstiness元素,文中提出了三种方法: 185 | 186 | * 移去多次特征点匹配; 187 | * 抑制图像内burstiness词的匹配得分; 188 | * 抑制图像间burstiness词的匹配得分。 189 | ### 理论推导 190 | 191 |
192 | ↥ Back To Top 193 |
194 | 195 | 196 | ## 系统和实验 197 | 198 | - [openvins测试方法](https://blog.csdn.net/weixin_43793960/article/details/110929933) 199 | 200 | 数据格式:# timestamp tx ty tz qx qy qz qw 201 | - [特征匹配测试方法](https://github.com/JiawangBian/FM-Bench) 202 | ``` 203 | 介绍系统 204 | 前端 205 | 后端 206 | 回环检测 207 | 实验结果 208 | 匹配效果对比 209 | 定位精度对比 210 | 回环准确率对比 211 | 212 | 213 | ``` 214 |
215 | ↥ Back To Top 216 |
217 | 218 | 219 | ## 总结和展望 220 | 221 | ``` 222 | 总结自己的工作 223 | 有哪些优点, 224 | 有哪些不足 225 | 展望未来可能的研究 226 | 227 | ``` 228 |
229 | ↥ Back To Top 230 |
231 | 232 | 233 | ## 致谢 234 | ``` 235 | 时光飞逝,三年的研究生生涯即将结束,我在成电已经度过了七年的求学生活。回首过往,收获满满,学习了大量专业知识,掌握了专业技能,心智和思想上不断成熟。 236 | 我在成电取得的每一份进步,除了自己的努力,更离不开老师、同学们的关心、支持与帮助!首先感谢实验室的负责老师程洪教授,程老师在科研和工作中的高标准、严要求,以及对待问题的坚持和拼搏都刻在学生的脑海里,为我遇到问题、解决问题提供参考。特别是程老师对我们传授的《金字塔原理》和SCQA分析法,成为了学生科研上乃至生活中的重要法宝。 237 | 感谢况逸群老师,在日常的科研学习过程中,给予了我很多帮助,平时都是称呼他为师兄。况师兄具有超高的科研能力和丰富的工程实践经验,他的指导让我少走了很多弯路,也使我从一个科研小白成长到现在具备独立解决问题的能力,在我的论文研究和撰写过程中也提出了许多宝贵意见,给予了我很大的帮助。 238 | 感谢项目组的汪玲老师,刚来实验室就进入汪老师的项目组,是她带我走进了科研的大门。汪老师对我悉心指导,帮助我渡过难关,让我学习与成长。 239 | 同时,感谢团队的詹惠琴老师、谢鸿钦老师,你们带我出去增长见识、一起讨论科学问题和修改项目方案。感谢邱静老师、李曙光老师、赵洋老师、陈路峰老师、黄瑞老师和其他曾提供宝贵意见的老师,让我获益良多。在这里,还要感谢黄清雨、罗双庆、欧波和冯林熙四位工程师,在日常的学习和生活中对我的指导和帮助。 240 | 感谢师兄谢林江、张亚东、黄星宇、方庆的无私奉献和倾囊相助,和你们在一起的日子充实而丰富。感谢同级的岳峥嵘同学、荀钰婷同学、李金洋同学、钟志超同学、王轶同学,在科研项目、日常生活和找工作过程中互相鼓励并共同进步。感谢我的室友杜凯,七年的室友生活即将结束,我们也将走向各自新的人生方向。感谢师弟葛睿、常俊萌。感谢你们在我学习和奋斗路上的帮助,祝你们都能学有所成,前程似锦。 241 | 感谢我的父母和其他家人,感谢你们含辛茹苦将我养大成人,感谢多年来对我学业和生活上的支持和鼓励,感谢你们对我的培养、包容和期盼,有了你们的关心和支持,我才能在追逐自己梦想的路上扬帆起航。 242 | 感谢所有给予我帮助和成长的人和事。 243 | 最后,谨向百忙之中抽出宝贵时间对我的论文给出评审意见的老师、学者和论文答辩的所有委员们致以最诚挚的敬意! 244 | 245 | ``` 246 |
247 | ↥ Back To Top 248 |
249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/二分查找和排序.md: -------------------------------------------------------------------------------- 1 | # 二分查找和排序 2 | [前往刷题](https://www.nowcoder.com/practice/d3df40bd23594118b57554129cadf47b?tpId=295&tqId=1499549&ru=%2Fpractice%2Fd3df40bd23594118b57554129cadf47b&qru=%2Fta%2Fformat-top101%2Fquestion-ranking&sourceUrl=%2Fexam%2Foj) 3 | 4 | 5 | - [BM17](#BM17) 6 | - [BM18](#BM18) 7 | - [BM19](#BM19) 8 | - [BM20](#BM20) 9 | - [BM21](#BM21) 10 | - [BM22](#BM22) 11 | 12 | ## BM17 13 | 14 | * BM17 二分查找-I 15 | 16 | 描述 17 | ``` 18 | 请实现无重复数字的升序数组的二分查找 19 | 20 | 给定一个 元素升序的、无重复数字的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标(下标从 0 开始),否则返回 -1 21 | 22 | 数据范围:0 \le len(nums) \le 2\times10^50≤len(nums)≤2×10 23 | 5 24 | , 数组中任意值满足 |val| \le 10^9∣val∣≤10 25 | 9 26 | 27 | 进阶:时间复杂度 O(\log n)O(logn) ,空间复杂度 O(1)O(1) 28 | ``` 29 | 30 | ```cpp 31 | class Solution { 32 | public: 33 | int search(vector& nums, int target) { 34 | int l = 0; 35 | int r = nums.size() - 1; 36 | //从数组首尾开始,直到二者相遇 fast-template 37 | while(l <= r){ 38 | //每次检查中点的值 39 | int m = (l + r) / 2; 40 | if(nums[m] == target) 41 | return m; 42 | //进入左的区间 43 | if(nums[m] > target) 44 | r = m - 1; 45 | //进入右区间 46 | else 47 | l = m + 1; 48 | } 49 | //未找到 50 | return -1; 51 | } 52 | }; 53 | ``` 54 |
55 | ↥ Back To Top 56 |
57 | 58 | ## BM18 59 | 60 | 61 | * BM18 二维数组中的查找 62 | 63 | 描述 64 | ``` 65 | 在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 66 | [ 67 | [1,2,8,9], 68 | [2,4,9,12], 69 | [4,7,10,13], 70 | [6,8,11,15] 71 | ] 72 | 给定 target = 7,返回 true。 73 | 74 | 给定 target = 3,返回 false。 75 | 76 | 数据范围:矩阵的长宽满足 0 \le n,m \le 5000≤n,m≤500 , 矩阵中的值满足 0 \le val \le 10^90≤val≤10 77 | 9 78 | 79 | 进阶:空间复杂度 O(1)O(1) ,时间复杂度 O(n+m)O(n+m) 80 | ``` 81 | 82 | 83 | ```cpp 84 | //从左下角开始搜索,必目标大就向上,小就向右边 85 | class Solution { 86 | public: 87 | bool Find(int target, vector > array) { 88 | //优先判断特殊 fast-template 89 | if(array.size() == 0) 90 | return false; 91 | int n = array.size(); 92 | if(array[0].size() == 0) 93 | return false; 94 | int m = array[0].size(); 95 | //从最左下角的元素开始往左或往上 96 | for(int i = n - 1, j = 0; i >= 0 && j < m; ){ 97 | //元素较大,往上走 98 | if(array[i][j] > target) 99 | i--; 100 | //元素较小,往右a走 101 | else if(array[i][j] < target) 102 | j++; 103 | else 104 | return true; 105 | } 106 | return false; 107 | } 108 | }; 109 | ``` 110 |
111 | ↥ Back To Top 112 |
113 | 114 | 115 | ## BM19 116 | 117 | 118 | * BM19 寻找峰值 119 | 120 | 描述 121 | ``` 122 | 给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。 123 | 1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于 124 | 2.假设 nums[-1] = nums[n] = -\infty−∞ 125 | 3.对于所有有效的 i 都有 nums[i] != nums[i + 1] 126 | 4.你可以使用O(logN)的时间复杂度实现此问题吗? 127 | 128 | 数据范围: 129 | 1 \le nums.length \le 2\times 10^5 \1≤nums.length≤2×10 130 | 5 131 | 132 | -2^{31}<= nums[i] <= 2^{31} - 1−2 133 | 31 134 | <=nums[i]<=2 135 | 31 136 | −1 137 | 138 | 如输入[2,4,1,2,7,8,4]时,会形成两个山峰,一个是索引为1,峰值为4的山峰,另一个是索引为5,峰值为8的山峰,如下图所示: 139 | ``` 140 | ![img](https://uploadfiles.nowcoder.com/images/20211014/423483716_1634212356346/9EB9CD58B9EA5E04C890326B5C1F471F) 141 | ```cpp 142 | class Solution { 143 | public: 144 | int findPeakElement(vector& nums) { 145 | int left = 0; 146 | int right = nums.size() - 1; 147 | //二分法 fast-template 148 | while(left < right){ 149 | int mid = (left + right) / 2; 150 | //右边是往下,不一定有坡峰 151 | if(nums[mid] > nums[mid + 1]) 152 | right = mid; 153 | //右边是往上,一定能找到波峰 154 | else 155 | left = mid + 1; 156 | } 157 | //其中一个波峰 158 | return right; 159 | } 160 | }; 161 | ``` 162 |
163 | ↥ Back To Top 164 |
165 | 166 | 167 | ## BM20 168 | 169 | 170 | * BM20 数组中的逆序对 171 | 172 | 描述 173 | ``` 174 | 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007 175 | 176 | 数据范围: 对于 50\%50% 的数据, size\leq 10^4size≤10 177 | 4 178 | 179 | 对于 100\%100% 的数据, size\leq 10^5size≤10 180 | 5 181 | 182 | 数组中所有数字的值满足 0 \le val \le 10000000≤val≤1000000 183 | 184 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(nlogn)O(nlogn) 185 | 输入描述: 186 | 题目保证输入的数组中没有的相同的数字 187 | ``` 188 | 189 | ```cpp 190 | class Solution { 191 | public: 192 | int mod = 1000000007; 193 | int mergeSort(int left, int right, vector& data, vector& temp){ 194 | // 停止划分 fast-template 195 | if (left >= right) 196 | return 0; 197 | //取中间 198 | int mid = (left + right) / 2; 199 | //左右划分 200 | int res = mergeSort(left, mid, data, temp) + mergeSort(mid + 1, right, data, temp); 201 | //防止溢出 202 | res %= mod; 203 | int i = left, j = mid + 1; 204 | for (int k = left; k <= right; k++) 205 | temp[k] = data[k]; 206 | for (int k = left; k <= right; k++) { 207 | if (i == mid + 1) 208 | data[k] = temp[j++]; 209 | else if (j == right + 1 || temp[i] <= temp[j]) 210 | data[k] = temp[i++]; 211 | //左边比右边大,答案增加 212 | else { 213 | data[k] = temp[j++]; 214 | // 统计逆序对 215 | res += mid - i + 1; 216 | } 217 | } 218 | return res % mod; 219 | } 220 | int InversePairs(vector data) { 221 | int n = data.size(); 222 | vector res(n); 223 | return mergeSort(0, n - 1, data, res); 224 | } 225 | }; 226 | ``` 227 |
228 | ↥ Back To Top 229 |
230 | 231 | 232 | ## BM21 233 | 234 | 235 | * BM21 旋转数组的最小数字 236 | 237 | 描述 238 | ``` 239 | 有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。 240 | 241 | 数据范围:1 \le n \le 100001≤n≤10000,数组中任意元素的值: 0 \le val \le 100000≤val≤10000 242 | 要求:空间复杂度:O(1)O(1) ,时间复杂度:O(logn)O(logn) 243 | ``` 244 | 245 | ```cpp 246 | class Solution { 247 | public: 248 | int minNumberInRotateArray(vector rotateArray) { 249 | int left = 0; 250 | int right = rotateArray.size() - 1; 251 | while(left < right){ 252 | int mid = (left + right) / 2; 253 | //最小的数字在mid右边 fast-template 254 | if(rotateArray[mid] > rotateArray[right]) 255 | left = mid + 1; 256 | //无法判断,一个一个试 257 | else if(rotateArray[mid] == rotateArray[right]) 258 | right--; 259 | //最小数字要么是mid要么在mid左边 260 | else 261 | right = mid; 262 | } 263 | return rotateArray[left]; 264 | } 265 | }; 266 | ``` 267 |
268 | ↥ Back To Top 269 |
270 | 271 | 272 | ## BM22 273 | 274 | 275 | * BM22 比较版本号 276 | 277 | 描述 278 | ``` 279 | 牛客项目发布项目版本时会有版本号,比如1.02.11,2.14.4等等 280 | 现在给你2个版本号version1和version2,请你比较他们的大小 281 | 版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订号可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号 282 | 每个版本号至少包含1个修订号。 283 | 修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。 284 | 285 | 比较规则: 286 | 一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1"和"0.01"的版本号是相等的 287 | 二. 如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,"1.1"的版本号小于"1.1.1"。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1 288 | 三. version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0. 289 | 290 | 数据范围: 291 | 1 <= version1.length, version2.length <= 10001<=version1.length,version2.length<=1000 292 | version1 和 version2 的修订号不会超过int的表达范围,即不超过 32 位整数 的范围 293 | 294 | 进阶: 时间复杂度 O(n)O(n) 295 | ``` 296 | 297 | ```cpp 298 | class Solution { 299 | public: 300 | int compare(string version1, string version2) { 301 | int n1 = version1.size(); 302 | int n2 = version2.size(); 303 | int i = 0, j = 0; 304 | //直到某个字符串结束 fast-template 305 | while(i < n1 || j < n2){ 306 | long long num1 = 0; 307 | //从下一个点前截取数字 308 | while(i < n1 && version1[i] != '.'){ 309 | num1 = num1 * 10 + (version1[i] - '0'); 310 | i++; 311 | } 312 | i++; //跳过点 313 | long long num2 = 0; 314 | //从下一个点前截取数字 315 | while(j < n2 && version2[j] != '.'){ 316 | num2 = num2 * 10 + (version2[j] - '0'); 317 | j++; 318 | } 319 | //跳过点 320 | j++; 321 | //比较数字大小 322 | if(num1 > num2) 323 | return 1; 324 | if(num1 < num2) 325 | return -1; 326 | } 327 | //版本号相同 328 | return 0; 329 | } 330 | }; 331 | ``` 332 |
333 | ↥ Back To Top 334 |
335 | 336 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | > @Author: [李琦](https://github.com/liuqian62) , [陈玥锦](https://github.com/210-297) , [周林峰](https://github.com/against43) ,[才昌照](https://github.com/caichangzhao) ,[荀钰婷](https://github.com/iredawen) ,[钟志超](https://github.com/WillenChung) ,[夏青云](https://github.com/delecloud),[李金洋](https://github.com/nankelli),[张亚东](https://github.com/WestMemoery),[杜凯](https://github.com/kayky233),[王轶](https://github.com/ybyzy) , [李天晓](https://github.com/EwrinCat) 13 | 14 | 15 | 17 | 18 | # This is my notebook 19 | 20 | 21 | * [一键安装ros等](https://fishros.github.io/install/#/) 22 | ``` 23 | wget http://fishros.com/install -O fishros && . fishros 24 | ``` 25 | 26 | 27 | 28 | 29 | 30 | ## 学习笔记 31 | * [python相关](./python相关) 32 | * [Linux使用](./linux使用) 33 | * [slam学习笔记](./slamNotes/slam学习笔记.md) 34 | * [slam资料和笔记](/slamNotes) 35 | * [激光SLAM](/slamNotes/激光SLAM/readme.md) 36 | * [3dGauss](/slamNotes/3dGauss_splatting/readme.md) 37 | 38 | ## 刷题找工作 39 |
40 | 点击查看:刷题找工作 41 | 42 | * [面试总结](./learnCpp/面经.md) 43 | 44 | * [基础四大件](https://github.com/liuqian62/notebook/tree/main/%E5%9F%BA%E7%A1%80%E5%9B%9B%E5%A4%A7%E4%BB%B6) 45 | * [c++](https://github.com/liuqian62/notebook/tree/main/learn%20c%2B%2B) 46 | * [刷题](https://github.com/liuqian62/notebook/tree/main/%E7%89%9B%E5%AE%A2%E7%BD%91%E5%88%B7%E9%A2%98%E7%AC%94%E8%AE%B0) 47 | 48 | 本来想自己总结的,但是别人已经弄好了,哈哈哈 49 | * [别人的总结](https://github.com/liuqian62/offerMachine) 50 | * [csnote非常全面](https://github.com/liuqian62/CS-Notes) 51 | 52 | 53 | 54 | 55 |
56 | 57 | | 资源网站 | 求职网站 | 58 | | :---: | :---: | 59 | |[代码随想录](https://programmercarl.com/)|[前程无忧](http://www.51job.com/)| 60 | |[力扣](https://leetcode.cn/problemset/all/)|[智联招聘](http://www.zhaopin.com/)| 61 | | [牛客网](https://www.nowcoder.com/exam/oj) | [BOSS直聘](https://www.zhipin.com/chengdu/) | 62 | | [菜鸟](https://www.runoob.com/) | [拉钩网](http://www.lagou.com/) | 63 | | [电子书(解压密码:4321)](https://github.com/imarvinle/awesome-cs-books) | [猎聘网](http://www.liepin.com/) | 64 | | [河畔就业](https://bbs.uestc.edu.cn/forum.php?mod=forumdisplay&fid=174) | [百度百聘](https://zhaopin.baidu.com/) | 65 | | [图解计算机基础](https://xiaolincoding.com/) | [58同城](http://www.58.com/) | 66 |
67 | 68 | 69 | * [校招避雷](https://github.com/forthespada/CampusShame) 70 |
71 | 72 | 73 | 74 | 75 |
76 | 点击查看:readme文件写作教程 77 | 78 | 79 | 80 | - [readme写作技巧](https://blog.csdn.net/weixin_43750377/article/details/107834499?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165223128416782391850797%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165223128416782391850797&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-15-107834499-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=readme%E8%B6%85%E9%93%BE%E6%8E%A5&spm=1018.2226.3001.4187) 81 | - [代码高亮](https://blog.csdn.net/bocongbo/article/details/118362609?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165223218716782390587998%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165223218716782390587998&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-20-118362609-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=readme%E5%86%99%E4%BD%9C&spm=1018.2226.3001.4187#:~:text=%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%B1%BB%E4%BC%BC%EF%BC%8C%E6%9B%B4%E6%8D%A2%60%60%60%E5%90%8E%E9%9D%A2%E4%B8%BA%E8%AF%AD%E8%A8%80%E5%90%8D%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9Apython%E3%80%81java%E3%80%81php) 82 | - [demo](https://markdown-it.github.io/) 83 | - [链接到文档标题](https://blog.csdn.net/henryhu712/article/details/110261893?ops_request_misc=&request_id=&biz_id=102&utm_term=markdown%E9%93%BE%E6%8E%A5%E5%88%B0%E6%A0%87%E9%A2%98&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-110261893.142^v10^pc_search_result_control_group,157^v12^control&spm=1018.2226.3001.4449) 84 | - [各种公式符号](https://blog.nowcoder.net/n/7d5d9ff47af74c288d19ba29e88c5643) 85 | - [插入公式](https://blog.csdn.net/qq_42951560/article/details/116501075) 86 | - [Equation Editor](https://latex.codecogs.com/) 87 | 88 | 89 | $$ 90 | Y = \begin{cases}1\quad \text {if \textcolor{orange}{stoke}} \\ 91 | 2\quad \text{if \textcolor{orange}{drug overdose};}\\ 92 | 3 \quad\text{if \textcolor{orange}{drug epileptic seizure}} 93 | \end{cases} 94 | $$ 95 | 96 | $$ 97 | Y = \textcolor{green}{\frac{x^2}{1+x^2}} 98 | $$ 99 | 100 | 101 | 102 | 103 |
104 | 105 |

106 |

107 |

108 |

109 |

110 |

111 |

112 |

113 |

114 |

115 |

116 |

117 |

118 |

119 |

120 |

121 |

122 |
123 | 124 | 131 | 132 |
133 | 134 |
135 | ↥ Back To Top 136 |
137 | 138 | * 居中 139 | ``` 140 |
141 |
142 |
143 | ``` 144 | -------------------------------------------------------------------------------- /slamNotes/readme.md: -------------------------------------------------------------------------------- 1 | # slam notes 2 | ## 目录 3 | 4 | - [资料](#资料) 5 | - [环境安装](#环境安装) 6 | - [各种库的使用](#各种库的使用) 7 | - [大佬的博客](#大佬的博客) 8 | - [我的主要工作](#我的主要工作) 9 | - [SLAM评估工具](#SLAM评估工具) 10 | - [SLAM找工作](#SLAM找工作) 11 | 12 | ## 资料 13 | - [常用开源方案简介和对比](./slam开源方案) 14 | - [视觉SLAM相关研究](https://github.com/wuxiaolang/Visual_SLAM_Related_Research) 15 | - [SLAM十四讲](https://github.com/liuqian62/notebook/blob/main/slamNotes/14%E8%AE%B2.md) 16 | - [多传感器融合定位知乎专栏](https://zhuanlan.zhihu.com/c_1114864226103037952) 17 | - [深蓝学院视觉slam](https://github.com/zhouyong1234/VIO-Course) 18 | - [深蓝学院激光slam](https://github.com/zhouyong1234/Laser-SLAM-Course) 19 | - [古月居](https://www.guyuehome.com/) 20 | 21 | 23 | 24 |
25 | ↥ Back To Top 26 |
27 | 28 | 29 | ## 环境安装 30 | * [ubuntu安装](https://blog.csdn.net/baidu_36602427/article/details/86548203?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266749016782395341493%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266749016782395341493&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-86548203-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=ubuntu18.04%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B&spm=1018.2226.3001.4449) 31 | * [ros安装](https://blog.csdn.net/weixin_50060664/article/details/121781535?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266766216782350951349%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266766216782350951349&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-121781535-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=ubuntu%E5%AE%89%E8%A3%85ros&spm=1018.2226.3001.4449) 32 | * [ros常用命令](https://blog.csdn.net/u010585964/article/details/78715130?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165551422316780366549949%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165551422316780366549949&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-4-78715130-null-null.142^v17^pc_rank_34,157^v15^new_3&utm_term=ros%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4&spm=1018.2226.3001.4187) 33 | * [各种库的安装](https://blog.csdn.net/Night___Raid/article/details/105113617?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266819116782350993650%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266819116782350993650&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-105113617-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=slam%E7%9A%84%E5%90%84%E7%A7%8D%E5%BA%93%E5%AE%89%E8%A3%85&spm=1018.2226.3001.4449) 34 | * [安装多个版本OpenCV](https://heyijia.blog.csdn.net/article/details/54575245?spm=1001.2014.3001.5502) 35 | * [d435i驱动安装和标定](https://blog.csdn.net/qq_35616298/article/details/116171823?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162942123216780271562120%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162942123216780271562120&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-1-116171823.first_rank_v2_pc_rank_v29&utm_term=%E9%94%99%E8%AF%AF%3A+%E6%97%A0%E6%B3%95%E9%AA%8C%E8%AF%81+faculty.cse.tamu.edu+%E7%9A%84%E7%94%B1+%E2%80%9CCN%3DInCommon+RSA+Server+CA%2COU%3DInCommon%2CO%3DInternet2%2CL%3DAnn+Arbor%2CST%3DMI%2CC%3DUS%E2%80%9D+%E9%A2%81%E5%8F%91%E7%9A%84%E8%AF%81%E4%B9%A6%3A&spm=1018.2226.3001.4187) 36 | * [ros2教程](http://fishros.com/#/fish_home) 37 | * [ros2交流社区](https://fishros.org.cn/forum/) 38 | 39 |
40 | ↥ Back To Top 41 |
42 | 43 | ## ros使用 44 | [ros学习笔记](ros学习笔记.md) 45 | 46 | [ros常用消息](ros常用消息.md) 47 | 48 | 49 | 50 |
51 | ↥ Back To Top 52 |
53 | 54 | 55 | ## 各种库的使用 56 | 57 | --[代码](https://github.com/liuqian62/lib_use) 58 | * [Eigen使用](https://blog.csdn.net/yxpandjay/article/details/80587916?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266842616782248567999%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266842616782248567999&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-80587916-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=eigen%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4449) 59 | * [Eigen平移旋转](https://blog.csdn.net/u011092188/article/details/77430988) 60 | * [g2o使用](https://blog.csdn.net/He3he3he/article/details/110007973?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266856216782246426329%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266856216782246426329&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-9-110007973-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=g2o%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4449) 61 | * [Ceres使用](https://blog.csdn.net/zzyczzyc/article/details/88937558?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266905516782395383342%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266905516782395383342&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-88937558-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=ceres%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4449) 62 | * [OpenCV使用](https://blog.csdn.net/zzx2016zzx/article/details/108691235?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165266957316781683948705%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165266957316781683948705&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-6-108691235-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=opencv%E6%95%99%E7%A8%8Bc%2B%2B&spm=1018.2226.3001.4449) 63 | * [OpenCV官方文档](https://docs.opencv.org/3.4.4/index.html) 64 | * [Sophus使用](https://blog.csdn.net/u011092188/article/details/77833022?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165267053516780357263815%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165267053516780357263815&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-77833022-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=Sophus%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4449) 65 | 66 |
67 | ↥ Back To Top 68 |
69 | 70 | 71 | ## 大佬的博客 72 | * [高翔](https://www.cnblogs.com/gaoxiang12/) 73 | * [贺一家](https://blog.csdn.net/heyijia0327?type=blog) 74 | * [紫薯萝卜](https://www.zhihu.com/people/mao-shu-yuan/posts) 75 | * [小吴同学](https://wym.netlify.app/) 76 | 77 | 78 | 85 | 86 | 87 |
88 | ↥ Back To Top 89 |
90 | 91 | 92 | ## 我的主要工作 93 | * [SLAM学习笔记](slam学习笔记.md) 94 | * [论文阅读](./slam论文阅读/) 95 | * [2021](2021.md) 96 | * 回环检测所需数据生成和发布 97 | * 双目改单目 98 | * 回环检测节点移植 99 | * 传感器数据发布和时间戳对齐 100 | * [2022](2022.md) 101 | * 特征跟踪改进(光流法改间接匹配方法、特征均匀化、运动信息加入) 102 | * 回环检测改进(前后帧贝叶斯推理、图像内和图像间相似性评分抑制) 103 | * [2023](2023.md) 104 | * do something 105 | 106 |
107 | ↥ Back To Top 108 |
109 | 110 | 111 | ## SLAM评估工具 112 | * [保存为TUM和KITTI格式](TUM_KITTI.md) 113 | * [博客教程](https://blog.csdn.net/weixin_41469272/article/details/119885449?ops_request_misc=&request_id=&biz_id=102&utm_term=rpg_trajectory_evaluation%E5%A4%9A%E8%BD%A8%E8%BF%B9&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-2-119885449.142^v66^control,201^v3^add_ask,213^v2^t3_esquery_v2&spm=1018.2226.3001.4187) 114 | 115 | 116 | * [evo](https://github.com/MichaelGrupp/evo) 117 | * [evo使用教程](https://blog.csdn.net/u011341856/article/details/104594392?spm=1001.2014.3001.5501) 118 | * [rpg_trajectory_evaluation](https://github.com/uzh-rpg/rpg_trajectory_evaluation) 119 | * [数据集](https://blog.csdn.net/crp997576280/article/details/103340020?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165284191416781432971813%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165284191416781432971813&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-103340020-null-null.142^v10^pc_search_result_control_group,157^v4^control&utm_term=slam%E6%95%B0%E6%8D%AE%E9%9B%86%E7%99%BE%E5%BA%A6%E7%BD%91%E7%9B%98&spm=1018.2226.3001.4187) 120 | * [tum](https://vision.in.tum.de/data/datasets/rgbd-dataset/download) 121 | * [newcollge](https://drive.google.com/drive/u/0/folders/15lTH5osZzZlDpcW7oXfR_2t8TNssNARS) 122 | * [awesome-slam-datasets](https://github.com/youngguncho/awesome-slam-datasets) 123 | 124 | 125 |
126 | ↥ Back To Top 127 |
128 | 129 | 130 | ## SLAM找工作 131 | * [面试问题整理](https://github.com/liuqian62/notebook/blob/main/slamNotes/SLAM%E9%9D%A2%E8%AF%95%E9%97%AE%E9%A2%98%E6%95%B4%E7%90%86.md) 132 | * [视觉slam面试题总结](https://blog.csdn.net/weixin_44580210/article/details/91790044) 133 | * [slam常见面试题](https://zhuanlan.zhihu.com/p/46694678) 134 | * [slam求职分享](https://zhuanlan.zhihu.com/p/68858564) 135 | * [面试SLAM算法实习生总结](https://zhuanlan.zhihu.com/p/76280626) 136 | 137 |
138 | ↥ Back To Top 139 |
140 | 141 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/双指针.md: -------------------------------------------------------------------------------- 1 | # 双指针 2 | 3 | ## 目录 4 | 5 | 6 | - [BM87](#BM87) 7 | - [BM88](#BM88) 8 | - [BM89](#BM89) 9 | - [BM90](#BM90) 10 | - [BM91](#BM91) 11 | - [BM92](#BM92) 12 | - [BM93](#BM93) 13 | - [BM94](#BM94) 14 | 15 | 16 | ## BM87 17 | * BM87 合并两个有序的数组 18 | 19 | 描述 20 | ``` 21 | 给出一个有序的整数数组 A 和有序的整数数组 B ,请将数组 B 合并到数组 A 中,变成一个有序的升序数组 22 | 23 | 数据范围: 0 \le n,m \le 1000≤n,m≤100,|A_i| <=100∣A 24 | i 25 | ​ 26 | ∣<=100, |B_i| <= 100∣B 27 | i 28 | ​ 29 | ∣<=100 30 | 31 | 注意: 32 | 1.保证 A 数组有足够的空间存放 B 数组的元素, A 和 B 中初始的元素数目分别为 m 和 n,A的数组空间大小为 m+n 33 | 2.不要返回合并的数组,将数组 B 的数据合并到 A 里面就好了,且后台会自动将合并后的数组 A 的内容打印出来,所以也不需要自己打印 34 | 3. A 数组在[0,m-1]的范围也是有序的 35 | ``` 36 | 37 | ```cpp 38 | class Solution { 39 | public: 40 | void merge(int A[], int m, int B[], int n) { 41 | //指向数组A的结尾 fast-template 42 | int i = m - 1; 43 | //指向数组B的结尾 44 | int j = n - 1; 45 | //指向数组A空间的结尾处 46 | int k = m + n - 1; 47 | //从两个数组最大的元素开始,直到某一个数组遍历完 48 | while(i >= 0 && j >= 0){ 49 | //将较大的元素放到最后 50 | if(A[i] > B[j]) 51 | A[k--] = A[i--]; 52 | else 53 | A[k--] = B[j--]; 54 | } 55 | //数组A遍历完了,数组B还有,则还需要添加到数组A前面 56 | if(i < 0){ 57 | while(j >= 0) 58 | A[k--] = B[j--]; 59 | //数组B遍历完了,数组A前面正好有,不用再添加 60 | } 61 | } 62 | }; 63 | ``` 64 | 65 |
66 | ↥ Back To Top 67 |
68 | 69 | 70 | 71 | ## BM88 72 | * BM88 判断是否为回文字符串 73 | 74 | 描述 75 | ``` 76 | 给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。 77 | 78 | 字符串回文指该字符串正序与其逆序逐字符一致。 79 | 80 | 数据范围:0 < n \le 10000000 84 | ```cpp 85 | class Solution { 86 | public: 87 | /** 88 | * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 89 | * 90 | * @param str string字符串 待判断的字符串 91 | * @return bool布尔型 92 | */ 93 | bool judge(string str) { 94 | // write code here 95 | int left = 0; 96 | int right = str.length()-1; 97 | while(left 110 | ↥ Back To Top 111 | 112 | 113 | 114 | 115 | ## BM89 116 | * BM89 合并区间 117 | 118 | 描述 119 | ``` 120 | 给出一组区间,请合并所有重叠的区间。 121 | 请保证合并后的区间按区间起点升序排列。 122 | 123 | 数据范围:区间组数 0 \le n \le 2 \times 10^50≤n≤2×10 124 | 5 125 | ,区间内 的值都满足 0 \le val \le 2 \times 10^50≤val≤2×10 126 | 5 127 | 128 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(nlogn)O(nlogn) 129 | 进阶:空间复杂度 O(val)O(val),时间复杂度O(val)O(val) 130 | ``` 131 | 132 | ```cpp 133 | /** 134 | * Definition for an interval. 135 | * struct Interval { 136 | * int start; 137 | * int end; 138 | * Interval() : start(0), end(0) {} 139 | * Interval(int s, int e) : start(s), end(e) {} 140 | * }; 141 | */ 142 | class Solution { 143 | public: 144 | static bool cmp(Interval& in1,Interval& in2){ 145 | return in1.start merge(vector &intervals) { 148 | vector res; 149 | if(intervals.size()==0){ 150 | return res; 151 | } 152 | sort(intervals.begin(),intervals.end(),cmp); 153 | res.push_back(intervals[0]); 154 | for(int i=1; i 167 | ↥ Back To Top 168 | 169 | 170 | 171 | 172 | ## BM90 173 | * BM90 最小覆盖子串 174 | 175 | 描述 176 | ``` 177 | 给出两个字符串 s 和 t,要求在 s 中找出最短的包含 t 中所有字符的连续子串。 178 | 179 | 数据范围:0 \le |S|,|T| \le100000≤∣S∣,∣T∣≤10000,保证s和t字符串中仅包含大小写英文字母 180 | 要求: 时间复杂度 O(n)O(n) 181 | 例如: 182 | S ="XDOYEZODEYXNZ"S="XDOYEZODEYXNZ" 183 | T ="XYZ"T="XYZ" 184 | 找出的最短子串为"YXNZ""YXNZ". 185 | 186 | 注意: 187 | 如果 s 中没有包含 t 中所有字符的子串,返回空字符串 “”; 188 | 满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。 189 | ``` 190 | 191 | ```cpp 192 | class Solution { 193 | public: 194 | //检查是否有小于0的 fast-template 195 | bool check(unordered_map& hash) { 196 | for (auto iter = hash.begin(); iter != hash.end(); iter++) { 197 | if (iter->second < 0) 198 | return false; 199 | } 200 | return true; 201 | } 202 | string minWindow(string S, string T) { 203 | int cnt = S.length() + 1; 204 | //记录目标字符串T的字符个数 205 | unordered_map hash; 206 | for (int i = 0; i < T.length(); i++) 207 | //初始化哈希表都为负数,找的时候再加为正 208 | hash[T[i]] -= 1; 209 | int slow = 0, fast = 0; 210 | //记录左右区间 211 | int left = -1, right = -1; 212 | for (; fast < S.length(); fast++) { 213 | char c = S[fast]; 214 | //目标字符匹配+1 215 | if (hash.count(c)) 216 | hash[c]++; 217 | //没有小于0的说明都覆盖了,缩小窗口 218 | while (check(hash)) { 219 | //取最优解 220 | if (cnt > fast - slow + 1) { 221 | cnt = fast - slow + 1; 222 | left = slow; 223 | right = fast; 224 | } 225 | char c = S[slow]; 226 | if (hash.count(c)) 227 | //缩小窗口的时候减1 228 | hash[c]--; 229 | //窗口缩小 230 | slow++; 231 | } 232 | } 233 | //找不到的情况 234 | if (left == -1) 235 | return ""; 236 | return string(S.begin() + left, S.begin() + (right + 1)); 237 | } 238 | }; 239 | ``` 240 | 241 |
242 | ↥ Back To Top 243 |
244 | 245 | 246 | 247 | ## BM91 248 | * BM91 反转字符串 249 | 250 | 描述 251 | ``` 252 | 写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000) 253 | 254 | 数据范围: 0 \le n \le 10000≤n≤1000 255 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 256 | ``` 257 | 258 | ```cpp 259 | class Solution { 260 | public: 261 | string solve(string str) { 262 | //左右双指针 fast-template 263 | int left = 0; 264 | int right = str.length() - 1; 265 | //两指针往中间靠 266 | while(left < right){ 267 | //交换两边字符 268 | swap(str[left], str[right]); 269 | left++; 270 | right--; 271 | } 272 | return str; 273 | } 274 | }; 275 | ``` 276 | 277 |
278 | ↥ Back To Top 279 |
280 | 281 | 282 | 283 | ## BM92 284 | * BM92 最长无重复子数组 285 | 286 | 描述 287 | ``` 288 | 给定一个长度为n的数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。 289 | 子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组 290 | 291 | 数据范围:0\le arr.length \le 10^50≤arr.length≤10 292 | 5 293 | ,0 < arr[i] \le 10^50 297 | ```cpp 298 | class Solution { 299 | public: 300 | int maxLength(vector& arr) { 301 | //哈希表记录窗口内非重复的数字 fast-template 302 | unordered_map mp; 303 | int res = 0; 304 | //设置窗口左右边界 305 | for (int left = 0, right = 0; right < arr.size(); right++) { 306 | //窗口右移进入哈希表统计出现次数 307 | mp[arr[right]]++; 308 | //出现次数大于1,则窗口内有重复 309 | while (mp[arr[right]] > 1) 310 | //窗口左移,同时减去该数字的出现次数 311 | mp[arr[left++]]--; 312 | //维护子数组长度最大值 313 | res = max(res, right - left + 1); 314 | } 315 | return res; 316 | } 317 | }; 318 | ``` 319 | 320 |
321 | ↥ Back To Top 322 |
323 | 324 | 325 | 326 | ## BM93 327 | * BM93 盛水最多的容器 328 | 329 | 描述 330 | ``` 331 | 给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水 332 | 1.你不能倾斜容器 333 | 2.当n小于2时,视为不能形成容器,请返回0 334 | 3.数据保证能容纳最多的水不会超过整形范围,即不会超过231-1 335 | 336 | 数据范围: 337 | 0<=height.length<=10^50<=height.length<=10 338 | 5 339 | 340 | 0<=height[i]<=10^40<=height[i]<=10 341 | 4 342 | 343 | 344 | 如输入的height为[1,7,3,2,4,5,8,2,7],那么如下图: 345 | ``` 346 | ![img](https://uploadfiles.nowcoder.com/images/20211105/301499_1636104759021/B9F3EB6BBC1EE9A63532E7EB494A11A7) 347 | ```cpp 348 | class Solution { 349 | public: 350 | int maxArea(vector& height) { 351 | //排除不能形成容器的情况 fast-template 352 | if (height.size() < 2) 353 | return 0; 354 | int res = 0; 355 | //双指针左右界 356 | int left = 0; 357 | int right = height.size() - 1; 358 | //共同遍历完所有的数组 359 | while (left < right) { 360 | //计算区域水容量 361 | int capacity = min(height[left], height[right]) * (right - left); 362 | //维护最大值 363 | res = max(res, capacity); 364 | //优先舍弃较短的边 365 | if (height[left] < height[right]) 366 | left++; 367 | else 368 | right--; 369 | } 370 | return res; 371 | } 372 | }; 373 | ``` 374 | 375 |
376 | ↥ Back To Top 377 |
378 | 379 | 380 | 381 | ## BM94 382 | * BM94 接雨水问题 383 | 384 | 描述 385 | ``` 386 | 给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度视为0) 387 | ``` 388 | ![img](https://uploadfiles.nowcoder.com/images/20210416/999991351_1618541247169/26A2E295DEE51749C45B5E8DD671E879) 389 | ```cpp 390 | class Solution { 391 | public: 392 | /** 393 | * max water 394 | * @param arr int整型vector the array 395 | * @return long长整型 396 | */ 397 | long long maxWater(vector& arr) { 398 | // write code here 399 | if(arr.size()<2){ 400 | return 0; 401 | } 402 | int left = 0; 403 | int right =arr.size()-1; 404 | int max_left=0; 405 | int max_right=0; 406 | int res = 0; 407 | while(left 422 | ↥ Back To Top 423 | 424 | 425 | -------------------------------------------------------------------------------- /牛客网刷题笔记/输入输出练习.md: -------------------------------------------------------------------------------- 1 | 2 | # 在线编程常见输入输出练习 [链接](https://ac.nowcoder.com/acm/contest/5657#question) 3 | 4 | 5 | ## 一行字符串输入得到数组 6 | 7 | ```cpp 8 | vector get_array(string s) { 9 |  vector ans; 10 |  int num = 0; 11 |  for(int i=0; i 26 | using namespace std; 27 | int main(){ 28 | int a; 29 | int sum=0; 30 | while(cin>>a){ 31 | sum+=a; 32 | if(cin.get()=='\n'){ 33 | cout< 49 | 点击查看:A+B(1) 50 | * 1.A+B(1) 51 | 52 | 输入:`输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。` 53 | 输出:`输出a+b的结果` 54 | 55 | ```cpp 56 | #include 57 | using namespace std; 58 | 59 | int main() 60 | { 61 | int a,b; 62 | while(cin>>a>>b){ 63 | if(a<1||a>1000||b<1||b>1000){ 64 | break; 65 | } 66 | cout< 73 | 74 |
75 | ↥ Back To Top 76 |
77 | 78 | 79 | ## 2 80 |
81 | 点击查看:A+B(2) 82 | * 2.A+B(2) 83 | 84 | 输入:`输入第一行包括一个数据组数t(1 <= t <= 100), 85 | 接下来每行包括两个正整数a,b(1 <= a, b <= 1000)` 86 | 输出:`输出a+b的结果` 87 | 88 | ```cpp 89 | #include 90 | using namespace std; 91 | 92 | int main(){ 93 | int t,a,b; 94 | cin>>t; 95 | while(cin>>a>>b){ 96 | cout< 104 | 105 |
106 | ↥ Back To Top 107 |
108 | 109 | 110 | ## 3 111 |
112 | 点击查看:A+B(3) 113 | * 3.A+B(3) 114 | 115 | 输入:`输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入` 116 | 输出:`输出a+b的结果` 117 | 118 | ```cpp 119 | #include 120 | using namespace std; 121 | int main(){ 122 | int a,b; 123 | while(cin>>a>>b){ 124 | if(a==0&&b==0) break; 125 | cout< 132 | 133 |
134 | ↥ Back To Top 135 |
136 | 137 | 138 | ## 4 139 |
140 | 点击查看:A+B(4) 141 | * 4.A+B(4) 142 | 143 | 输入:`输入数据包括多组。 144 | 每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。 145 | 接下来n个正整数,即需要求和的每个正整数。` 146 | 输出:`每组数据输出求和的结果` 147 | 148 | ```cpp 149 | #include 150 | using namespace std; 151 | int main(){ 152 | int a,t; 153 | int sum=0; 154 | while(1){ 155 | cin>>t; 156 | if(t==0) break; 157 | while(--t>=0){ 158 | cin>>a; 159 | sum+=a; 160 | } 161 | cout< 169 | 170 |
171 | ↥ Back To Top 172 |
173 | 174 | 175 | ## 5 176 |
177 | 点击查看:A+B(5) 178 | * 5.A+B(5) 179 | 180 | 输入:`输入的第一行包括一个正整数t(1 <= t <= 100), 表示数据组数。 181 | 接下来t行, 每行一组数据。 182 | 每行的第一个整数为整数的个数n(1 <= n <= 100)。 183 | 接下来n个正整数, 即需要求和的每个正整数。` 184 | 输出:`每组数据输出求和的结果` 185 | 186 | ```cpp 187 | #include 188 | using namespace std; 189 | int main(){ 190 | int t,n; 191 | cin>>t; 192 | while(--t>=0){ 193 | cin>>n; 194 | int sum=0, a; 195 | while(--n>=0){ 196 | cin>>a; 197 | sum+=a; 198 | } 199 | cout< 206 | 207 |
208 | ↥ Back To Top 209 |
210 | 211 | 212 | ## 6 213 |
214 | 点击查看:A+B(6) 215 | * 6.A+B(6) 216 | 217 | 输入:`输入数据有多组, 每行表示一组输入数据。 218 | 每行的第一个整数为整数的个数n(1 <= n <= 100)。 219 | 接下来n个正整数, 即需要求和的每个正整数。` 220 | 输出:`每组数据输出求和的结果` 221 | 222 | ```cpp 223 | #include 224 | using namespace std; 225 | int main(){ 226 | int a,t; 227 | while(cin>>t){ 228 | int sum=0; 229 | while(--t>=0){ 230 | cin>>a; 231 | sum+=a; 232 | } 233 | cout< 240 | 241 |
242 | ↥ Back To Top 243 |
244 | 245 | 246 | ## 7 247 |
248 | 点击查看:A+B(7) 249 | * 7.A+B(7) 250 | 251 | 输入:`输入数据有多组, 每行表示一组输入数据。 252 | 每行不定有n个整数,空格隔开。(1 <= n <= 100)。` 253 | 输出:`每组数据输出求和的结果` 254 | 255 | ```cpp 256 | #include 257 | using namespace std; 258 | int main(){ 259 | int a; 260 | int sum=0; 261 | while(cin>>a){ 262 | sum+=a; 263 | if(cin.get()=='\n'){ 264 | cout< 273 | 274 |
275 | ↥ Back To Top 276 |
277 | 278 | 279 | ## 8 280 |
281 | 点击查看:字符串排序(1) 282 | * 8.字符串排序(1) 283 | 284 | 输入:`输入有两行,第一行n, 285 | 第二行是n个字符串,字符串之间用空格隔开` 286 | 输出:`输出一行排序后的字符串,空格隔开,无结尾空格` 287 | 288 | ```cpp 289 | #include 290 | #include 291 | #include 292 | #include 293 | using namespace std; 294 | int main(){ 295 | int n; 296 | vector st; 297 | cin>>n; 298 | while(n--){ 299 | string tmp; 300 | cin>>tmp; 301 | st.push_back(tmp); 302 | } 303 | sort(st.begin(),st.end()); 304 | for(uint i=0;i 315 | 316 |
317 | ↥ Back To Top 318 |
319 | 320 | 321 | ## 9 322 |
323 | 点击查看:字符串排序(2) 324 | * 9.字符串排序(2) 325 | 326 | 输入:`多个测试用例,每个测试用例一行。 327 | 每行通过空格隔开,有n个字符,n<100` 328 | 输出:`对于每组测试用例,输出一行排序过的字符串,每个字符串通过空格隔开` 329 | 330 | ```cpp 331 | #include 332 | #include 333 | #include 334 | #include 335 | using namespace std; 336 | int main(){ 337 | vector st; 338 | string tmp; 339 | while(cin>>tmp){ 340 | st.push_back(tmp); 341 | if(cin.get()=='\n'){ 342 | sort(st.begin(),st.end()); 343 | for(uint i=0;i 358 | 359 |
360 | ↥ Back To Top 361 |
362 | 363 | 364 | ## 10 365 |
366 | 点击查看:字符串排序(3) 367 | * 10.字符串排序(3) 368 | 369 | 输入:`多个测试用例,每个测试用例一行。 370 | 每行通过,隔开,有n个字符,n<100` 371 | 输出:`对于每组用例输出一行排序后的字符串,用','隔开,无结尾空格` 372 | 373 | ```cpp 374 | #include 375 | #include 376 | #include 377 | #include 378 | using namespace std; 379 | int main(){ 380 | vector st; 381 | string s,tmp; 382 | while(cin>>s){ 383 | for(char i:s){ 384 | if(i==','){ 385 | st.push_back(tmp); 386 | tmp.clear(); 387 | }else{ 388 | tmp.push_back(i); 389 | } 390 | } 391 | st.push_back(tmp); 392 | tmp.clear(); 393 | sort(st.begin(),st.end()); 394 | for(uint i=0;i 408 | 409 |
410 | ↥ Back To Top 411 |
412 | 413 | ## 11 414 |
415 | 点击查看:本地自测通过提交为0 416 | * 11.本地自测通过提交为0 417 | 418 | 输入:`输入有多组测试用例,每组空格隔开两个整数。` 419 | 输出:`对于每组数据输出一行两个整数的和` 420 | 421 | ```cpp 422 | #include 423 | using namespace std; 424 | 425 | int main() 426 | { 427 | long int a,b; 428 | while(cin>>a>>b){ 429 | cout< 436 | 437 |
438 | ↥ Back To Top 439 |
440 | 441 | ## 链表的输入 442 | ```cpp 443 | #include 444 | using namespace std; 445 | struct ListNode{ 446 | int val; 447 | ListNode* next; 448 | ListNode(int x):val(x),next(NULL){} 449 | }; 450 | //反转链表 451 | ListNode* rever(ListNode* phead){ 452 | if(!phead||!phead->next) return NULL; 453 | ListNode* p1=NULL; 454 | ListNode* p2=phead; 455 | while(p2){ 456 | ListNode* tmp = p2->next; 457 | p2->next=p1; 458 | p1=p2; 459 | p2=tmp; 460 | } 461 | return p1; 462 | } 463 | int main() 464 | { 465 | int n; 466 | ListNode* head = new ListNode(0); 467 | ListNode* cur = head; 468 | while(cin>>n){ 469 | ListNode* cur1=new ListNode(n); 470 | cur->next=cur1; 471 | cur=cur->next; 472 | } 473 | head=head->next; 474 | ListNode* pre=rever(head); 475 | while(pre){ 476 | cout<val<<","; 477 | pre=pre->next; 478 | } 479 | return 0; 480 | } 481 | ``` 482 | 483 | * 双向链表 484 | ```cpp 485 | #include 486 | using namespace std; 487 | struct ListNode{ 488 | int val; 489 | ListNode* next; 490 | ListNode* prev; 491 | ListNode(int x):val(x),next(NULL),prev(NULL){} 492 | }; 493 | 494 | int main() 495 | { 496 | int n; 497 | ListNode* head = new ListNode(0); 498 | ListNode* cur = head; 499 | while(cin>>n){ 500 | ListNode* cur1=new ListNode(n); 501 | cur->next=cur1; 502 | cur1->prev=cur; 503 | cur=cur->next; 504 | } 505 | ListNode* pre=head->next; 506 | while(pre){ 507 | cout<val<<","; 508 | pre=pre->next; 509 | } 510 | cout<val<<","; 513 | cur=cur->prev; 514 | } 515 | return 0; 516 | } 517 | ``` 518 |
519 | ↥ Back To Top 520 |
521 | 522 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/递归和回溯.md: -------------------------------------------------------------------------------- 1 | # 递归和回溯 2 | 3 | ## 目录 4 | 5 | - [BM55](#BM55) 6 | - [BM56](#BM56) 7 | - [BM57](#BM57) 8 | - [BM58](#BM58) 9 | - [BM59](#BM59) 10 | - [BM60](#BM60) 11 | - [BM61](#BM61) 12 | 13 | 14 | 15 | ## BM55 16 | * BM55 没有重复项数字的全排列 17 | 18 | 描述 19 | ``` 20 | 给出一组数字,返回该组数字的所有排列 21 | 例如: 22 | [1,2,3]的所有排列如下 23 | [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1]. 24 | (以数字在数组中的位置靠前为优先级,按字典序排列输出。) 25 | 26 | 数据范围:数字个数 0 < n \le 60 30 | ```cpp 31 | class Solution { 32 | public: 33 | void dfs(vector& tmp,vector& used,vector num,vector>& res){ 34 | int n= num.size(); 35 | if(tmp.size()==n){ 36 | res.push_back(tmp); 37 | return; 38 | } 39 | for(int i=0;i< n;i++){ 40 | if(!used[i]){ 41 | used[i]=true; 42 | tmp.push_back(num[i]); 43 | dfs(tmp,used,num,res); 44 | tmp.pop_back(); 45 | used[i]=false; 46 | } 47 | } 48 | } 49 | vector > permute(vector &num) { 50 | vectortmp; 51 | vectorused(num.size(),false); 52 | vector> res; 53 | dfs(tmp,used,num,res); 54 | return res; 55 | } 56 | }; 57 | ``` 58 | 59 |
60 | ↥ Back To Top 61 |
62 | 63 | 64 | ## BM56 65 | * BM56 有重复项数字的全排列 66 | 67 | 描述 68 | ``` 69 | 给出一组可能包含重复项的数字,返回该组数字的所有排列。结果以字典序升序排列。 70 | 71 | 数据范围: 0 < n \le 80 75 | ```cpp 76 | class Solution { 77 | public: 78 | vector > permuteUnique(vector &num) { 79 | vector> res; 80 | sort(num.begin(),num.end()); 81 | vector tmp; 82 | vector used(num.size(),false); 83 | dfs(tmp,num,used,res); 84 | return res; 85 | 86 | } 87 | void dfs(vector& tmp,vector num, vector& used,vector>& res){ 88 | if(tmp.size()==num.size()){ 89 | res.push_back(tmp); 90 | return; 91 | } 92 | for(int i=0;i< num.size();i++){ 93 | if(used[i]) continue; 94 | if(i!=0&&num[i]==num[i-1]&&used[i-1]) continue; 95 | used[i]=true; 96 | tmp.push_back(num[i]); 97 | dfs(tmp,num,used,res); 98 | tmp.pop_back(); 99 | used[i]=false; 100 | } 101 | } 102 | }; 103 | ``` 104 | 105 |
106 | ↥ Back To Top 107 |
108 | 109 | 110 | ## BM57 111 | * BM57 岛屿数量 112 | 113 | 描述 114 | ``` 115 | 给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。 116 | 岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。 117 | 例如: 118 | 输入 119 | [ 120 | [1,1,0,0,0], 121 | [0,1,0,1,1], 122 | [0,0,0,1,1], 123 | [0,0,0,0,0], 124 | [0,0,1,1,1] 125 | ] 126 | 对应的输出为3 127 | (注:存储的01数据其实是字符'0','1') 128 | ``` 129 | 130 | ```cpp 131 | class Solution { 132 | public: 133 | //深度优先遍历与i,j相邻的所有1 fast-template 134 | void dfs(vector>& grid, int i, int j) { 135 | int n = grid.size(); 136 | int m = grid[0].size(); 137 | // 置为0 138 | grid[i][j] = '0'; 139 | //后续四个方向遍历 140 | if(i - 1 >= 0 && grid[i - 1][j] == '1') 141 | dfs(grid, i - 1, j); 142 | if(i + 1 < n && grid[i + 1][j] == '1') 143 | dfs(grid, i + 1,j); 144 | if(j - 1 >= 0 && grid[i][j - 1] == '1') 145 | dfs(grid, i, j - 1); 146 | if(j + 1 < m && grid[i][j + 1] == '1') 147 | dfs(grid, i, j + 1); 148 | } 149 | int solve(vector >& grid) { 150 | int n = grid.size(); 151 | //空矩阵的情况 152 | if (n == 0) 153 | return 0; 154 | int m = grid[0].size(); 155 | //记录岛屿数 156 | int count = 0; 157 | // 遍历矩阵 158 | for(int i = 0; i < n; i++){ 159 | for(int j = 0; j < m; j++){ 160 | //遍历到1的情况 161 | if(grid[i][j] == '1'){ 162 | //计数 163 | count++; 164 | //将与这个1相邻的所有1置为0 165 | dfs(grid, i, j); 166 | } 167 | } 168 | } 169 | return count; 170 | } 171 | }; 172 | ``` 173 | 174 |
175 | ↥ Back To Top 176 |
177 | 178 | 179 | ## BM58 180 | * BM58 字符串的排列 181 | 182 | 描述 183 | ``` 184 | 输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。 185 | 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 186 | ``` 187 | ![img](https://uploadfiles.nowcoder.com/images/20211008/557336_1633676660853/6226390B4185DB132AFFDB10F09F8BEB) 188 | ```cpp 189 | class Solution { 190 | public: 191 | void recursion(vector &res, string &str, string &temp, vector &vis){ 192 | //临时字符串满了加入输出 fast-template 193 | if(temp.length() == str.length()){ 194 | res.push_back(temp); 195 | return; 196 | } 197 | //遍历所有元素选取一个加入 198 | for(int i = 0; i < str.length(); i++){ 199 | //如果该元素已经被加入了则不需要再加入了 200 | if(vis[i]) 201 | continue; 202 | if(i > 0 && str[i - 1] == str[i] && !vis[i - 1]) 203 | //当前的元素str[i]与同一层的前一个元素str[i-1]相同且str[i-1]已经用过了 204 | continue; 205 | //标记为使用过 206 | vis[i] = 1; 207 | //加入临时字符串 208 | temp.push_back(str[i]); 209 | recursion(res, str, temp, vis); 210 | //回溯 211 | vis[i] = 0; 212 | temp.pop_back(); 213 | } 214 | } 215 | vector Permutation(string str) { 216 | //先按字典序排序,使重复字符串相邻 217 | sort(str.begin(), str.end()); 218 | //标记每个位置的字符是否被使用过 219 | vector vis(str.size(), 0); 220 | vector res; 221 | string temp; 222 | // 递归获取 223 | recursion(res, str, temp, vis); 224 | return res; 225 | } 226 | }; 227 | ``` 228 | 229 |
230 | ↥ Back To Top 231 |
232 | 233 | 234 | ## BM59 235 | * BM59 N皇后问题 236 | 237 | 描述 238 | ``` 239 | N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后, 240 | 要求:任何两个皇后不同行,不同列也不在同一条斜线上, 241 | 求给一个整数 n ,返回 n 皇后的摆法数。 242 | 243 | 数据范围: 1 \le n \le 91≤n≤9 244 | 要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n!)O(n!) 245 | 246 | 例如当输入4时,对应的返回值为2, 247 | 对应的两种四皇后摆位如下图所示: 248 | ``` 249 | ![img](https://uploadfiles.nowcoder.com/images/20211204/423483716_1638606211798/CFE342EBEEFB9E6839E6ED216B889F16) 250 | 251 | ![img](https://uploadfiles.nowcoder.com/images/20210715/57300254_1626357870939/8106FE54AB450BE909187F5990879887) 252 | ```cpp 253 | class Solution { 254 | public: 255 | //判断皇后是否符合条件 fast-template 256 | bool isValid(vector &pos, int row, int col){ 257 | //遍历所有已经记录的行 258 | for(int i = 0; i < row; i++){ 259 | //不能同行同列同一斜线 260 | if(row == i || col == pos[i] || abs(row - i) == abs(col - pos[i])) 261 | return false; 262 | } 263 | return true; 264 | } 265 | //递归查找皇后种类 266 | void recursion(int n, int row, vector & pos, int &res){ 267 | //完成全部行都选择了位置 268 | if(row == n){ 269 | res++; 270 | return; 271 | } 272 | //遍历所有列 273 | for(int i = 0; i < n; i++){ 274 | //检查该位置是否符合条件 275 | if(isValid(pos, row, i)){ 276 | //加入位置 277 | pos[row] = i; 278 | //递归继续查找 279 | recursion(n, row + 1, pos, res); 280 | } 281 | } 282 | } 283 | int Nqueen(int n) { 284 | int res = 0; 285 | //下标为行号,元素为列号,记录皇后位置 286 | vector pos(n, 0); 287 | //递归 288 | recursion(n, 0, pos, res); 289 | return res; 290 | } 291 | }; 292 | ``` 293 | 294 |
295 | ↥ Back To Top 296 |
297 | 298 | 299 | ## BM60 300 | * BM60 括号生成 301 | 302 | 描述 303 | ``` 304 | 给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。 305 | 例如,给出n=3,解集为: 306 | "((()))", "(()())", "(())()", "()()()", "()(())" 307 | 308 | 数据范围:0 \le n \le 100≤n≤10 309 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(2^n)O(2 310 | n 311 | ) 312 | ``` 313 | 314 | ```cpp 315 | class Solution { 316 | public: 317 | /** 318 | * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 319 | * 320 | * 321 | * @param n int整型 322 | * @return string字符串vector 323 | */ 324 | vector generateParenthesis(int n) { 325 | // write code here 326 | string tmp; 327 | vector res; 328 | dfs(0,0,tmp,n,res); 329 | return res; 330 | } 331 | void dfs(int left, int right, string tmp,int n, vector& res){ 332 | if(left==n&& right==n){ 333 | res.push_back(tmp); 334 | return; 335 | } 336 | if(left 347 | ↥ Back To Top 348 | 349 | 350 | 351 | ## BM61 352 | * BM61 矩阵最长递增路径 353 | 354 | 描述 355 | ``` 356 | 给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。 357 | 这个路径必须满足以下条件: 358 | 359 | 1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。 360 | 2. 你不能走重复的单元格。即每个格子最多只能走一次。 361 | 362 | 数据范围:1 \le n,m \le 10001≤n,m≤1000,0 \le matrix[i][j] \le 10000≤matrix[i][j]≤1000 363 | 进阶:空间复杂度 O(nm)O(nm) ,时间复杂度 O(nm)O(nm) 364 | 365 | 例如:当输入为[[1,2,3],[4,5,6],[7,8,9]]时,对应的输出为5, 366 | 其中的一条最长递增路径如下图所示: 367 | ``` 368 | ![img](https://uploadfiles.nowcoder.com/images/20211201/423483716_1638350164758/A6B05D015D3BE3C77C34DDF224044A1F) 369 | 370 | 具体做法 371 | ``` 372 | step 1:使用一个dp数组记录iii,jjj处的单元格拥有的最长递增路径,这样在递归过程中如果访问到就不需要重复访问。 373 | step 2:遍历矩阵每个位置,都可以作为起点,并维护一个最大的路径长度的值。 374 | step 3:对于每个起点,使用dfs查找最长的递增路径:只要下一个位置比当前的位置数字大,就可以深入,同时累加路径长度。 375 | ``` 376 | ```cpp 377 | class Solution { 378 | public: 379 | //记录四个方向 fast-template 380 | int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 381 | int n, m; 382 | //深度优先搜索,返回最大单元格数 383 | int dfs(vector > &matrix, vector > &dp, int i, int j) { 384 | if(dp[i][j] != 0) 385 | return dp[i][j]; 386 | dp[i][j]++; 387 | for(int k = 0; k < 4; k++){ 388 | int nexti = i + dirs[k][0]; 389 | int nextj = j + dirs[k][1]; 390 | //判断条件 391 | if (nexti >= 0 && nexti < n && nextj >= 0 && nextj < m && matrix[nexti][nextj] > matrix[i][j]) 392 | dp[i][j] = max(dp[i][j], dfs(matrix, dp, nexti, nextj) + 1); 393 | } 394 | return dp[i][j]; 395 | } 396 | int solve(vector >& matrix) { 397 | //矩阵不为空 398 | if(matrix.size() == 0 || matrix[0].size() == 0) 399 | return 0; 400 | int res = 0; 401 | n = matrix.size(); 402 | m = matrix[0].size(); 403 | //i,j处的单元格拥有的最长递增路径 404 | vector > dp (n, vector (m)); 405 | for(int i = 0; i < n; i++) 406 | for (int j = 0; j < m; j++) 407 | //更新最大值 408 | res = max(res, dfs(matrix, dp, i, j)); 409 | return res; 410 | } 411 | }; 412 | ``` 413 | 414 |
415 | ↥ Back To Top 416 |
417 | 418 | -------------------------------------------------------------------------------- /牛客网刷题笔记/面试必刷TOP101/堆栈队列.md: -------------------------------------------------------------------------------- 1 | # 堆栈队列 2 | 3 | ## 目录 4 | 5 | - [BM42](#BM42) 6 | - [BM43](#BM43) 7 | - [BM44](#BM44) 8 | - [BM45](#BM45) 9 | - [BM46](#BM46) 10 | - [BM47](#BM47) 11 | - [BM48](#BM48) 12 | - [BM49](#BM49) 13 | 14 | 15 | 16 | ## BM42 17 | * BM42 用两个栈实现队列 18 | 19 | 描述 20 | ``` 21 | 用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。 22 | 23 | 数据范围: n\le1000n≤1000 24 | 要求:存储n个元素的空间复杂度为 O(n)O(n) ,插入与删除的时间复杂度都是 O(1)O(1) 25 | ``` 26 | 27 | ```cpp 28 | class Solution 29 | { 30 | public: 31 | void push(int node) { 32 | stack1.push(node); 33 | 34 | } 35 | 36 | int pop() { 37 | int res; 38 | if(!stack2.empty()){ 39 | res = stack2.top(); 40 | stack2.pop(); 41 | return res; 42 | }else{ 43 | while(!stack1.empty()){ 44 | stack2.push(stack1.top()); 45 | stack1.pop(); 46 | } 47 | } 48 | res= stack2.top(); 49 | stack2.pop(); 50 | return res; 51 | 52 | } 53 | 54 | private: 55 | stack stack1; 56 | stack stack2; 57 | }; 58 | ``` 59 | 60 |
61 | ↥ Back To Top 62 |
63 | 64 | 65 | ## BM43 66 | * BM43 包含min函数的栈 67 | 68 | 描述 69 | ``` 70 | 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。 71 | 72 | 此栈包含的方法有: 73 | push(value):将value压入栈中 74 | pop():弹出栈顶元素 75 | top():获取栈顶元素 76 | min():获取栈中最小元素 77 | 78 | 数据范围:操作数量满足 0 \le n \le 300 \0≤n≤300 ,输入的元素满足 |val| \le 10000 \∣val∣≤10000 79 | 进阶:栈的各个操作的时间复杂度是 O(1)\O(1) ,空间复杂度是 O(n)\O(n) 80 | 81 | 示例: 82 | 输入: ["PSH-1","PSH2","MIN","TOP","POP","PSH1","TOP","MIN"] 83 | 输出: -1,2,1,-1 84 | 解析: 85 | "PSH-1"表示将-1压入栈中,栈中元素为-1 86 | "PSH2"表示将2压入栈中,栈中元素为2,-1 87 | “MIN”表示获取此时栈中最小元素==>返回-1 88 | "TOP"表示获取栈顶元素==>返回2 89 | "POP"表示弹出栈顶元素,弹出2,栈中元素为-1 90 | "PSH1"表示将1压入栈中,栈中元素为1,-1 91 | "TOP"表示获取栈顶元素==>返回1 92 | “MIN”表示获取此时栈中最小元素==>返回-1 93 | ``` 94 | 95 | ```cpp 96 | class Solution { 97 | public: 98 | //用于栈的push 与 pop fast-template 99 | stack s1; 100 | //用于存储最小min 101 | stack s2; 102 | void push(int value) { 103 | s1.push(value); 104 | //空或者新元素较小,则入栈 105 | if(s2.empty() || s2.top() > value) 106 | s2.push(value); 107 | else 108 | //重复加入栈顶 109 | s2.push(s2.top()); 110 | } 111 | void pop() { 112 | s1.pop(); 113 | s2.pop(); 114 | } 115 | int top() { 116 | return s1.top(); 117 | } 118 | int min() { 119 | return s2.top(); 120 | } 121 | }; 122 | ``` 123 | 124 |
125 | ↥ Back To Top 126 |
127 | 128 | 129 | ## BM44 130 | * BM44 有效括号序列 131 | 132 | 描述 133 | ``` 134 | 给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列 135 | 括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。 136 | 137 | 数据范围:字符串长度 0\le n \le 100000≤n≤10000 138 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 139 | ``` 140 | 141 | ```cpp 142 | class Solution { 143 | public: 144 | bool isValid(string s) { 145 | //辅助栈 fast-template 146 | stack st; 147 | //遍历字符串 148 | for(int i = 0; i < s.length(); i++){ 149 | //遇到左小括号 150 | if(s[i] == '(') 151 | //期待遇到右小括号 152 | st.push(')'); 153 | //遇到左中括号 154 | else if(s[i] == '[') 155 | //期待遇到右中括号 156 | st.push(']'); 157 | //遇到左打括号 158 | else if(s[i] == '{') 159 | //期待遇到右打括号 160 | st.push('}'); 161 | //必须有左括号的情况下才能遇到右括号 162 | else if(st.empty()) 163 | return false; 164 | //右括号匹配则弹出 165 | else if(st.top() == s[i]) 166 | st.pop(); 167 | } 168 | //栈中是否还有元素 169 | return st.empty(); 170 | } 171 | }; 172 | ``` 173 | 174 |
175 | ↥ Back To Top 176 |
177 | 178 | 179 | ## BM45 180 | * BM45 滑动窗口的最大值 181 | 182 | 描述 183 | ``` 184 | 给定一个长度为 n 的数组 nums 和滑动窗口的大小 size ,找出所有滑动窗口里数值的最大值。 185 | 186 | 例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。 187 | 188 | 数据范围: 1 \le size \le n \le 100001≤size≤n≤10000,数组中每个元素的值满足 |val| \le 10000∣val∣≤10000 189 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 190 | 191 | ``` 192 | 193 | ```cpp 194 | class Solution { 195 | public: 196 | vector maxInWindows(const vector& num, unsigned int size) { 197 | vector res; 198 | //窗口大于数组长度的时候,返回空 fast-template 199 | if(size <= num.size() && size != 0){ 200 | //双向队列 201 | deque dq; 202 | //先遍历一个窗口 203 | for(int i = 0; i < size; i++){ 204 | //去掉比自己先进队列的小于自己的值 205 | while(!dq.empty() && num[dq.back()] < num[i]) 206 | dq.pop_back(); 207 | dq.push_back(i); 208 | } 209 | //遍历后续数组元素 210 | for(int i = size; i < num.size(); i++){ 211 | res.push_back(num[dq.front()]); 212 | while(!dq.empty() && dq.front() < (i - size + 1)) 213 | //弹出窗口移走后的值 214 | dq.pop_front(); 215 | //加入新的值前,去掉比自己先进队列的小于自己的值 216 | while(!dq.empty() && num[dq.back()] < num[i]) 217 | dq.pop_back(); 218 | dq.push_back(i); 219 | } 220 | res.push_back(num[dq.front()]); 221 | } 222 | return res; 223 | } 224 | }; 225 | ``` 226 | 227 |
228 | ↥ Back To Top 229 |
230 | 231 | 232 | ## BM46 233 | * BM46 最小的K个数 234 | 235 | 描述 236 | ``` 237 | 给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。 238 | 数据范围:0\le k,n \le 100000≤k,n≤10000,数组中每个数的大小0 \le val \le 10000≤val≤1000 239 | 要求:空间复杂度 O(n)O(n) ,时间复杂度 O(nlogn)O(nlogn) 240 | ``` 241 | 242 | ```cpp 243 | class Solution { 244 | public: 245 | vector GetLeastNumbers_Solution(vector input, int k) { 246 | vector res; 247 | //排除特殊情况 fast-template 248 | if(k == 0 || input.size() == 0) 249 | return res; 250 | priority_queue q; 251 | //构建一个k个大小的堆 252 | for(int i = 0; i < k; i++) 253 | q.push(input[i]); 254 | for(int i = k; i < input.size(); i++){ 255 | //较小元素入堆 256 | if(q.top() > input[i]){ 257 | q.pop(); 258 | q.push(input[i]); 259 | } 260 | } 261 | //堆中元素取出入vector 262 | for(int i = 0; i < k; i++){ 263 | res.push_back(q.top()); 264 | q.pop(); 265 | } 266 | return res; 267 | } 268 | }; 269 | ``` 270 | 271 |
272 | ↥ Back To Top 273 |
274 | 275 | 276 | ## BM47 277 | * BM47 寻找第K大 278 | 279 | 描述 280 | ``` 281 | 有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。 282 | 283 | 给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。 284 | 要求:时间复杂度 O(nlogn)O(nlogn),空间复杂度 O(1)O(1) 285 | 数据范围:0\le n \le 10^50≤n≤10 286 | 5 287 | , 1 \le K \le n1≤K≤n,数组中每个元素满足 0 \le val \le 10^90≤val≤10 288 | 9 289 | ``` 290 | ![img](https://uploadfiles.nowcoder.com/images/20220330/397721558_1648640954779/F4E329B8F3EA5F301F7B038444F5A83A) 291 | ```cpp 292 | class Solution { 293 | public: 294 | //常规的快排划分,但这次是大数在左 fast-template 295 | int partion(vector& a, int low, int high){ 296 | int temp = a[low]; 297 | while(low < high){ 298 | //小于标杆的在右 299 | while(low < high && a[high] <= temp) 300 | high--; 301 | if(low == high) 302 | break; 303 | else 304 | a[low] = a[high]; 305 | //大于标杆的在左 306 | while(low < high && a[low] >= temp) 307 | low++; 308 | if(low == high) 309 | break; 310 | else 311 | a[high] = a[low]; 312 | } 313 | a[low] = temp; 314 | return low; 315 | } 316 | int quickSort(vector& a, int low, int high, int K){ 317 | //先进行一轮划分,p下标左边的都比它大,下标右边都比它小 318 | int p = partion(a, low, high); 319 | //若p刚好是第K个点,则找到 320 | if(K == p - low + 1) 321 | return a[p]; 322 | //从头到p超过k个数组,则目标在左边 323 | else if(p - low + 1 > K) 324 | //递归左边 325 | return quickSort(a, low, p - 1, K); 326 | else 327 | //否则,在右边,递归右边,但是需要减去左边更大的数字的数量 328 | return quickSort(a, p + 1, high, K - (p - low + 1)); 329 | } 330 | int findKth(vector a, int n, int K) { 331 | return quickSort(a, 0, n - 1, K); 332 | } 333 | }; 334 | ``` 335 | 336 |
337 | ↥ Back To Top 338 |
339 | 340 | 341 | ## BM48 342 | * BM48 数据流中的中位数 343 | 344 | 描述 345 | ``` 346 | 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。 347 | 348 | 数据范围:数据流中数个数满足 1 \le n \le 1000 \1≤n≤1000 ,大小满足 1 \le val \le 1000 \1≤val≤1000 349 | 350 | 进阶: 空间复杂度 O(n) \O(n) , 时间复杂度 O(nlogn) \O(nlogn) 351 | ``` 352 | 353 | ```cpp 354 | class Solution { 355 | public: 356 | //记录输入流 fast-template 357 | vector val; 358 | void Insert(int num) { 359 | if(val.empty()) 360 | //val中没有数据,直接加入 361 | val.push_back(num); 362 | //val中有数据,需要插入排序 363 | else{ 364 | int i = 0; 365 | //遍历找到插入点 366 | for(; i < val.size(); i++){ 367 | if(num <= val[i]){ 368 | break; 369 | } 370 | } 371 | val.insert(val.begin() + i, num); 372 | } 373 | } 374 | double GetMedian() { 375 | int n = val.size(); 376 | //奇数个数字 377 | if(n % 2 == 1){ 378 | //类型转换 379 | return double(val[n / 2]); 380 | } 381 | //偶数个数字 382 | else{ 383 | double a = val[n / 2]; 384 | double b = val[n / 2 - 1]; 385 | return (a + b) / 2; 386 | } 387 | } 388 | }; 389 | ``` 390 | 391 |
392 | ↥ Back To Top 393 |
394 | 395 | 396 | ## BM49 397 | * BM49 表达式求值 398 | 399 | 描述 400 | ``` 401 | 请写一个整数计算器,支持加减乘三种运算和括号。 402 | 403 | 数据范围:0\le |s| \le 1000≤∣s∣≤100,保证计算结果始终在整型范围内 404 | 405 | 要求:空间复杂度: O(n)O(n),时间复杂度 O(n)O(n) 406 | ``` 407 | 408 | ```cpp 409 | class Solution { 410 | public: 411 | vector function(string s, int index){ 412 | stack stack; 413 | int num = 0; 414 | char op = '+'; 415 | int i; 416 | for(i = index; i < s.length(); i++){ 417 | //数字转换成int数字 fast-template 418 | if(isdigit(s[i])){ 419 | num = num * 10 + s[i] - '0'; 420 | if(i != s.length() - 1) 421 | continue; 422 | } 423 | //碰到'('时,把整个括号内的当成一个数字处理 424 | if(s[i] == '('){ 425 | //递归处理括号 426 | vector res = function(s, i + 1); 427 | num = res[0]; 428 | i = res[1]; 429 | if(i != s.length() - 1) 430 | continue; 431 | } 432 | switch(op){ 433 | //加减号先入栈 434 | case '+': 435 | stack.push(num); 436 | break; 437 | case '-': 438 | //相反数 439 | stack.push(-num); 440 | break; 441 | //优先计算乘号 442 | case '*': 443 | int temp = stack.top(); 444 | stack.pop(); 445 | stack.push(temp * num); 446 | break; 447 | } 448 | num = 0; 449 | //右括号结束递归 450 | if(s[i] == ')') 451 | break; 452 | else 453 | op = s[i]; 454 | } 455 | int sum = 0; 456 | //栈中元素相加 457 | while(!stack.empty()){ 458 | sum += stack.top(); 459 | stack.pop(); 460 | } 461 | return vector {sum, i}; 462 | } 463 | int solve(string s) { 464 | return function(s, 0)[0]; 465 | } 466 | }; 467 | ``` 468 | 469 |
470 | ↥ Back To Top 471 |
472 | 473 | -------------------------------------------------------------------------------- /牛客网刷题笔记/算法入门/数据结构.md: -------------------------------------------------------------------------------- 1 | # 数据结构 2 | 3 | ## 目录 4 | 5 | - [栈](#栈) 6 | - [AB1](#AB1) 7 | - [AB2](#AB2) 8 | - [AB3](#AB3) 9 | - [AB4](#AB4) 10 | - [AB5](#AB5) 11 | - [AB6](#AB6) 12 | 13 | - [队列](#队列) 14 | - [AB7](#AB7) 15 | - [AB8](#AB8) 16 | 17 | - [链表](#链表) 18 | - [AB9](#AB9) 19 | - [AB10](#AB10) 20 | - [AB11](#AB11) 21 | - [AB12](#AB12) 22 | 23 | 24 | 25 | - [图论](#图论) 26 | - [AB13](#AB13) 27 | - [AB14](#AB14) 28 | - [AB15](#AB15) 29 | 30 | 31 | - [二叉树](#二叉树) 32 | - [AB16](#AB16) 33 | - [AB17](#AB17) 34 | 35 | - [堆](#堆) 36 | - [AB18](#AB18) 37 | 38 | 39 | ## 栈 40 | 41 | 42 | ### AB1 43 | * AB1 【模板】栈 44 | 45 | 描述 46 | ``` 47 | 请你实现一个栈。 48 | 操作: 49 | push x:将 加x\x 入栈,保证 x\x 为 int 型整数。 50 | pop:输出栈顶,并让栈顶出栈 51 | top:输出栈顶,栈顶不出栈 52 | 输入描述: 53 | 第一行为一个正整数 n\n ,代表操作次数。(1 \leq n \leq 100000)(1≤n≤100000) 54 | 接下来的 n\n ,每行为一个字符串,代表一个操作。保证操作是题目描述中三种中的一种。 55 | 56 | 57 | 输出描述: 58 | 如果操作为push,则不输出任何东西。 59 | 如果为另外两种,若栈为空,则输出 "error“ 60 | 否则按对应操作输出。 61 | ``` 62 | 63 | ```cpp 64 | #include 65 | using namespace std; 66 | 67 | class Stack { 68 | public: 69 | Stack(int size_){ 70 | index = 0; 71 | size = size_; 72 | arr = new int[size]; 73 | } 74 | void push(int x){ 75 | if(index>= size){ 76 | int *tmp = arr; 77 | size *=2; 78 | arr = new int[size]; 79 | memcpy(arr, tmp, sizeof(int)*index); 80 | delete []tmp; 81 | } 82 | arr[index++]= x; 83 | } 84 | int pop(){ 85 | if(index==0){ 86 | cout<<"error"<>n; 107 | Stack stk(n); 108 | string s; 109 | while(cin >> s){ 110 | if(s=="push"){ 111 | cin>>n; 112 | stk.push(n); 113 | } 114 | else if(s=="pop") stk.pop(); 115 | else stk.top(); 116 | } 117 | return 0; 118 | } 119 | ``` 120 | 121 |
122 | ↥ Back To Top 123 |
124 | 125 | 126 | ### AB2 127 | 128 | * AB2 栈的压入、弹出序列 129 | 130 | 描述 131 | ``` 132 | 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。 133 | 1. 0<=pushV.length == popV.length <=1000 134 | 2. -1000<=pushV[i]<=1000 135 | 3. pushV 的所有数字均不相同 136 | ``` 137 | 具体做法 138 | 139 | step 1:准备一个辅助栈,两个下标分别访问两个序列。 140 | step 2:辅助栈为空或者栈顶不等于出栈数组当前元素,就持续将入栈数组加入栈中。 141 | step 3:栈顶等于出栈数组当前元素就出栈。 142 | step 4:当入栈数组访问完,出栈数组无法依次弹出,就是不匹配的,否则两个序列都访问完就是匹配的。 143 | 144 | ![img](https://uploadfiles.nowcoder.com/images/20220421/397721558_1650532143383/7F25B229A4900F6E066BE03E92B0492E) 145 | 146 | ```cpp 147 | class Solution { 148 | public: 149 | bool IsPopOrder(vector pushV,vector popV) { 150 | int n = pushV.size(); 151 | //辅助栈 152 | stack s; 153 | //遍历入栈的下标 154 | int j = 0; 155 | //遍历出栈的数组 156 | for(int i = 0; i < n; i++){ 157 | //入栈:栈为空或者栈顶不等于出栈数组 158 | while(j < n && (s.empty() || s.top() != popV[i])){ 159 | s.push(pushV[j]); 160 | j++; 161 | } 162 | //栈顶等于出栈数组 163 | if(s.top() == popV[i]) 164 | s.pop(); 165 | //不匹配序列 166 | else 167 | return false; 168 | } 169 | return true; 170 | } 171 | }; 172 | ``` 173 | 174 |
175 | ↥ Back To Top 176 |
177 | 178 | ### AB3 179 | 180 | * AB3 dosomething 181 | 182 | 描述 183 | ``` 184 | 给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列 185 | 括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。 186 | 187 | 数据范围:字符串长度 0\le n \le 100000≤n≤10000 188 | 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 189 | ``` 190 | 191 | 核心思想: 192 | 193 | 每次遇到'(','{','['这三种字符的时候,将字符入栈stk;而每次遇到')','}',']'这三种字符的时候则让对应的匹配字符出栈。具体规则如下: 194 | 1)引入辅助栈stk,遍历字符串,每次遇到'(','{','['字符的时候将字符入栈stk 195 | 2)当遇到')','}',']'字符的时候,则检查栈是否空,且顶元素是否为匹配元素(如{和}匹配等),如果栈空或者栈顶元素不为匹配元素则括号序列不合法 196 | 3)当栈非空,且栈顶元素为匹配元素,则栈顶元素出栈。 197 | 4)循环匹配字符串,直到每次字符处理完 198 | 5)检查栈stk是否为空,栈为空则序列合法,否则不合法(当括号以正确顺序关闭时则最后的栈为空) 199 | 200 | ![img](https://uploadfiles.nowcoder.com/images/20210718/9970047_1626609454058/6973900DD42B3AF6C4400356AE10B770) 201 | ```cpp 202 | class Solution { 203 | public: 204 | bool isValid(string s) { 205 | //辅助栈 fast-template 206 | stack st; 207 | //遍历字符串 208 | for(int i = 0; i < s.length(); i++){ 209 | //遇到左小括号 210 | if(s[i] == '(') 211 | //期待遇到右小括号 212 | st.push(')'); 213 | //遇到左中括号 214 | else if(s[i] == '[') 215 | //期待遇到右中括号 216 | st.push(']'); 217 | //遇到左打括号 218 | else if(s[i] == '{') 219 | //期待遇到右打括号 220 | st.push('}'); 221 | //必须有左括号的情况下才能遇到右括号 222 | else if(st.empty()) 223 | return false; 224 | //右括号匹配则弹出 225 | else if(st.top() == s[i]) 226 | st.pop(); 227 | } 228 | //栈中是否还有元素 229 | return st.empty(); 230 | } 231 | }; 232 | ``` 233 | 234 |
235 | ↥ Back To Top 236 |
237 | 238 | ### AB4 239 | 240 | * AB4 逆波兰表达式求值 241 | 242 | 描述 243 | ``` 244 | 给定一个逆波兰表达式,求表达式的值。 245 | 246 | 数据范围:表达式长度满足 1≤n≤10^4 247 | ,表达式中仅包含数字和 + ,- , * , / ,其中数字的大小满足 |val| ≤200 。 248 | ``` 249 | 250 | 解题思路 251 | 252 | 逆波兰表达式求值的过程总是先列出运算符前面两个数字,然后将这两个数字进行相应运算,得到一个新的数字,这个数又与后面的数进行相应运算,直到结束。 253 | 254 | 所以,可以先新建一个栈,当遇到数字时,直接压入栈中,遇到运算符时,先取出栈顶的两个数字,进行相应运算,再压回栈中。最后栈中剩下的那个元素即是表达式的值。 255 | 256 | ![img](https://uploadfiles.nowcoder.com/images/20220114/100241712_1642167889585/5D99B6A70EE4701B5D348BD506621531) 257 | 258 | 259 | ```cpp 260 | class Solution { 261 | public: 262 | /** 263 | * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 264 | * 265 | * 266 | * @param tokens string字符串vector 267 | * @return int整型 268 | */ 269 | int evalRPN(vector& tokens) { 270 | // write code here 271 | stack st; 272 | for(int i = 0;i 294 | ↥ Back To Top 295 | 296 | 297 | ### AB5 298 | 299 | * AB5 点击消除 300 | 301 | 描述 302 | ``` 303 | 牛牛拿到了一个字符串。 304 | 他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。 305 | 但相同而不相邻、不相同的相邻字母都是不可以被消除的。 306 | 牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么? 307 | ``` 308 | 309 | ```cpp 310 | #include 311 | using namespace std; 312 | 313 | int main(){ 314 | string s; 315 | cin>>s; 316 | stackst; 317 | int n = s.length(); 318 | for(int i=0;i ans; 328 | while(!st.empty()){ 329 | ans.push(st.top()); 330 | st.pop(); 331 | } 332 | while(!ans.empty()){ 333 | cout< 343 | ↥ Back To Top 344 | 345 | 346 | ### AB6 347 | 348 | * AB6 表达式求值 349 | 350 | 描述 351 | ``` 352 | 请写一个整数计算器,支持加减乘三种运算和括号。 353 | 354 | 数据范围:0≤∣s∣≤100,保证计算结果始终在整型范围内 355 | 356 | 要求:空间复杂度: O(n),时间复杂度 O(n) 357 | ``` 358 | 359 | ```cpp 360 | class Solution { 361 | public: 362 | vector function(string s, int index){ 363 | stack stack; 364 | int num = 0; 365 | char op = '+'; 366 | int i; 367 | for(i = index; i < s.length(); i++){ 368 | //数字转换成int数字 fast-template 369 | if(isdigit(s[i])){ 370 | num = num * 10 + s[i] - '0'; 371 | if(i != s.length() - 1) 372 | continue; 373 | } 374 | //碰到'('时,把整个括号内的当成一个数字处理 375 | if(s[i] == '('){ 376 | //递归处理括号 377 | vector res = function(s, i + 1); 378 | num = res[0]; 379 | i = res[1]; 380 | if(i != s.length() - 1) 381 | continue; 382 | } 383 | switch(op){ 384 | //加减号先入栈 385 | case '+': 386 | stack.push(num); 387 | break; 388 | case '-': 389 | //相反数 390 | stack.push(-num); 391 | break; 392 | //优先计算乘号 393 | case '*': 394 | int temp = stack.top(); 395 | stack.pop(); 396 | stack.push(temp * num); 397 | break; 398 | } 399 | num = 0; 400 | //右括号结束递归 401 | if(s[i] == ')') 402 | break; 403 | else 404 | op = s[i]; 405 | } 406 | int sum = 0; 407 | //栈中元素相加 408 | while(!stack.empty()){ 409 | sum += stack.top(); 410 | stack.pop(); 411 | } 412 | return vector {sum, i}; 413 | } 414 | int solve(string s) { 415 | return function(s, 0)[0]; 416 | } 417 | }; 418 | ``` 419 | 420 |
421 | ↥ Back To Top 422 |
423 | 424 | 425 | 426 | 427 | ## 队列 428 | ### AB7 429 | 430 | * AB7 【模板】队列 431 | 432 | 描述 433 | ``` 434 | 请你实现一个队列。 435 | 操作: 436 | push x:将 x 加入队尾,保证 x 为 int 型整数。 437 | pop:输出队首,并让队首出队 438 | front:输出队首:队首不出队 439 | ``` 440 | 441 | ```cpp 442 | #include 443 | #include 444 | using namespace std; 445 | 446 | class node{ 447 | public: 448 | int x; 449 | node* next = nullptr; 450 | node(int x){ 451 | this->x =x; 452 | } 453 | }; 454 | 455 | class queue{ 456 | private: 457 | node* pfront = nullptr; 458 | node* pend = nullptr; 459 | public: 460 | void push(int x){ 461 | node* tmp = new node(x); 462 | if(pfront == nullptr){ 463 | pfront = tmp; 464 | pend = tmp; 465 | }else{ 466 | pend->next = tmp; 467 | pend= tmp; 468 | } 469 | } 470 | void pop(){ 471 | if(pfront==nullptr){ 472 | cout<<"error"<x<next; 482 | free(tmp); 483 | } 484 | } 485 | } 486 | void front(){ 487 | if(pfront==nullptr){ 488 | cout<<"error"<x<>n; 497 | queue q; 498 | for(int i=0;i>op; 501 | if(op=="push"){ 502 | int x; 503 | cin>>x; 504 | q.push(x); 505 | }else if(op=="pop"){ 506 | q.pop(); 507 | }else if(op=="front"){ 508 | q.front(); 509 | } 510 | } 511 | return 0; 512 | } 513 | ``` 514 | 515 |
516 | ↥ Back To Top 517 |
518 | 519 | ### AB8 520 | * AB8 【模板】循环队列 521 | 522 | 描述 523 | ``` 524 | 请你实现一个循环队列,该循环队列可利用的空间大小等于nn个int型变量的大小。 525 | 操作: 526 | push x:将xx加入到循环队列尾端。若循环队列已满,输出"full"(不含引号),否则不输出任何内容。保证xx为int型整数。 527 | front:输出队首元素,队首不出队。若队列为空,输出"empty"(不含引号)。 528 | pop:输出队首元素,且队首出队。若队列为空,输出"empty"(不含引号)。 529 | ``` 530 | 531 | ```cpp 532 | 533 | ``` 534 | 535 |
536 | ↥ Back To Top 537 |
538 | 539 | 540 | 541 | ## 链表 542 | ### AB1 543 | 544 | * AB1 dosomething 545 | 546 | 描述 547 | ``` 548 | 549 | ``` 550 | 551 | ```cpp 552 | 553 | ``` 554 | 555 |
556 | ↥ Back To Top 557 |
558 | 559 | 560 | ## 图论 561 | ### AB1 562 | * AB1 dosomething 563 | 564 | 描述 565 | ``` 566 | 567 | ``` 568 | 569 | ```cpp 570 | 571 | ``` 572 | 573 |
574 | ↥ Back To Top 575 |
576 | 577 | 578 | ## 二叉树 579 | ### AB1 580 | * AB1 dosomething 581 | 582 | 描述 583 | ``` 584 | 585 | ``` 586 | 587 | ```cpp 588 | 589 | ``` 590 | 591 |
592 | ↥ Back To Top 593 |
594 | 595 | 596 | ## 堆 597 | ### AB1 598 | * AB1 dosomething 599 | 600 | 描述 601 | ``` 602 | 603 | ``` 604 | 605 | ```cpp 606 | 607 | ``` 608 | 609 |
610 | ↥ Back To Top 611 |
612 | 613 | 614 | -------------------------------------------------------------------------------- /牛客网刷题笔记/顺序刷题.md: -------------------------------------------------------------------------------- 1 | ## 目录 2 | - [1. 矩阵中的路径](#1-矩阵中的路径) 3 | - [2. 机器人的运动范围](#2-机器人的运动范围) 4 | - [3. 剪绳子](#3-剪绳子) 5 | - [4. 正则化表达式匹配](4-正则化表达式匹配) 6 | - [5. 树的子结构](#5-树的子结构) 7 | - [6. 二叉搜索树的后序遍历序列](#6-二叉搜索树的后序遍历序列) 8 | - [7. 二叉树中和为某一值的路径(二)](#7-二叉树中和为某一值的路径二) 9 | - [8. 复杂链表的复制](#8-复杂链表的复制) 10 | - [9. 字符串的排列](#9-字符串的排列) 11 | - [10.数组的逆序对](#10-数组的逆序对) 12 | - [11.二叉搜索树的第k个节点](#11-二叉搜索树的第k个节点) 13 | - [12.连续子数组的最大和](#12-连续子数组的最大和) 14 | - [13.在二叉树中找到两个节点的最近公共祖先](#13-在二叉树中找到两个节点的最近公共祖先) 15 | - [14.冒泡排序](#14-冒泡排序) 16 | - [15.滑动窗口的最大值](#15-滑动窗口的最大值) 17 | 18 | ### 1. 矩阵中的路径 19 | 20 | 描述: 21 | ```请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 22 | 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。 23 | 以上转换过程如下图所示: 24 | ``` 25 | ![img](https://uploadfiles.nowcoder.com/images/20210715/397721558_1626336820199/6D7F11F6465F19627B99E8097812E8ED) 26 | 27 | ```cpp 28 | class Solution { 29 | public: 30 | bool dfs(vector >& matrix, int n, int m, int i, int j, string word, int k, vector >& flag){ 31 | if(i < 0 || i >= n || j < 0 || j >= m || (matrix[i][j] != word[k]) || (flag[i][j] == true)) 32 | //下标越界、字符不匹配、已经遍历过不能重复 33 | return false; 34 | //k为记录当前第几个字符 35 | if(k == word.length() - 1) 36 | return true; 37 | flag[i][j] = true; 38 | //该结点任意方向可行就可 39 | if(dfs(matrix, n, m, i - 1, j, word, k + 1, flag) 40 | ||dfs(matrix, n, m, i + 1, j, word, k + 1, flag) 41 | ||dfs(matrix, n, m, i, j - 1, word, k + 1, flag) 42 | ||dfs(matrix, n, m, i , j + 1, word, k + 1, flag)) 43 | return true; 44 | //没找到经过此格的,此格未被占用 45 | flag[i][j] = false; 46 | return false; 47 | } 48 | bool hasPath(vector >& matrix, string word) { 49 | //优先处理特殊情况 50 | if(matrix.size() == 0) 51 | return false; 52 | int n = matrix.size(); 53 | int m = matrix[0].size(); 54 | //初始化flag矩阵记录是否走过 55 | vector > flag(n, vector(m, false)); 56 | //遍历矩阵找起点 57 | for(int i = 0; i < n; i++){ 58 | for(int j = 0; j < m; j++){ 59 | //通过dfs找到路径 60 | if(dfs(matrix, n, m, i, j, word, 0, flag)) 61 | return true; 62 | } 63 | } 64 | return false; 65 | } 66 | }; 67 | 68 | ``` 69 | 70 |
71 | ↥ Back To Top 72 |
73 | 74 | 75 | ### 2. 机器人的运动范围 76 | 77 | 描述:`地上有一个 rows 行和 cols 列的方格。坐标从 [0,0] 到 [rows-1,cols-1] 。一个机器人从坐标 [0,0] 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 threshold 的格子。 例如,当 threshold 为 18 时,机器人能够进入方格 [35,37] ,因为 3+5+3+7 = 18。但是,它不能进入方格 [35,38] ,因为 3+5+3+8 = 19 。请问该机器人能够达到多少个格子?` 78 | ![img](https://uploadfiles.nowcoder.com/images/20220422/397721558_1650642588160/A5357C76ADED26150B5EC117648074B1) 79 | 80 | ```cpp 81 | class Solution { 82 | public: 83 | int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; 84 | int res = 0; 85 | int cal(int n){ 86 | int sum = 0; 87 | while(n){ 88 | sum += (n%10); 89 | n /= 10; 90 | } 91 | return sum; 92 | } 93 | 94 | void dfs(int i, int j, int rows, int cols, int threshold, vector> &vis){ 95 | if(i<0 ||i>=rows ||j<0 ||j>=cols||!vis[i][j]) return; 96 | 97 | if(cal(i)+cal(j)> threshold) return; 98 | 99 | res += 1; 100 | vis[i][j]=false; 101 | for(int k=0; k<4; ++k){ 102 | dfs(i+dir[k][0], j+dir[k][1], rows,cols,threshold,vis); } 103 | } 104 | 105 | 106 | int movingCount(int threshold, int rows, int cols) { 107 | if(threshold<=0) 108 | return 1; 109 | 110 | vector> vis(rows, vector(cols, true)); 111 | dfs(0,0,rows,cols,threshold,vis); 112 | return res; 113 | } 114 | }; 115 | 116 | ``` 117 | 118 |
119 | ↥ Back To Top 120 |
121 | 122 | 123 | ### 3. 剪绳子 124 | 125 | 描述: 126 | ``` 127 | 给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m 、 n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1],...,k[m] 。请问 k[1]*k[2]*...*k[m] 可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18 。 128 | 以上转换过程如下图所示: 129 | ``` 130 | ![img](https://uploadfiles.nowcoder.com/images/20220420/397721558_1650461340893/1005941E85C8E6FED32A1CE0DDA4AC11) 131 | 132 | ```cpp 133 | class Solution { 134 | public: 135 | 136 | int cutRope(int n) { 137 | // write code here 138 | if (n <=3){ 139 | return n -1; 140 | } 141 | vector dp(n+1, 0); 142 | dp[1] = 1; 143 | dp[2] = 2; 144 | dp[3] = 3; 145 | dp[4] = 4; 146 | for (int i = 5; i<=n; ++i){ 147 | for (int j=1;j 158 | ↥ Back To Top 159 | 160 | 161 | 162 | ### 4. 正则化表达式匹配 163 | 164 | 描述: 165 | ``` 166 | 请实现一个函数用来匹配包括'.'和'*'的正则表达式。 167 | 1.模式中的字符'.'表示任意一个字符 168 | 2.模式中的字符'*'表示它前面的字符可以出现任意次(包含0次)。 169 | 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配 170 | 以上转换过程如下图所示: 171 | ``` 172 | ![img](https://uploadfiles.nowcoder.com/images/20220219/397721558_1645241476200/183DF8D4E2E67604DA434FF48590872E) 173 | 174 | ```cpp 175 | class Solution { 176 | public: 177 | /** 178 | * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 179 | * 180 | * 181 | * @param str string字符串 182 | * @param pattern string字符串 183 | * @return bool布尔型 184 | */ 185 | bool match(string str, string pattern) { 186 | // write code here 187 | int n1=str.length(); 188 | int n2=pattern.length(); 189 | vector> dp(n1+1, vector(n2+1, false)); 190 | dp[0][0]=true; 191 | for(int i=2; i<=n2;++i){ 192 | if(pattern[i-1] =='*') 193 | dp[0][i]=dp[0][i-2]; 194 | } 195 | 196 | for(int i=1;i<=n1;++i){ 197 | for(int j=1; j<=n2;++j){ 198 | if(pattern[j-1]!='*'&&(pattern[j-1]=='.'||pattern[j-1]==str[i-1])){ 199 | dp[i][j]=dp[i-1][j-1]; 200 | }else if(j>=2 && pattern[j-1]=='*'){ 201 | if(pattern[j-2]=='.'||pattern[j-2]==str[i-1]) 202 | dp[i][j]=dp[i-1][j]||dp[i][j-2]; 203 | else 204 | dp[i][j]=dp[i][j-2]; 205 | } 206 | } 207 | } 208 | return dp[n1][n2]; 209 | } 210 | }; 211 | ``` 212 | 213 |
214 | ↥ Back To Top 215 |
216 | 217 | 218 | ### 5. 树的子结构 219 | 220 | 描述: 221 | ``` 222 | 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) 223 | 224 | 考察树的基础知识与递归的思路,深度优先搜索。 225 | 以上转换过程如下图所示: 226 | ``` 227 | ```cpp 228 | /* 229 | struct TreeNode { 230 | int val; 231 | struct TreeNode *left; 232 | struct TreeNode *right; 233 | TreeNode(int x) : 234 | val(x), left(NULL), right(NULL) { 235 | } 236 | };*/ 237 | class Solution { 238 | public: 239 | bool IsSame(TreeNode *pRoot1, TreeNode * pRoot2){ 240 | bool left=true,right=true; 241 | if(!pRoot1 || pRoot1->val !=pRoot2->val){ 242 | return false; 243 | } 244 | if(pRoot2->left) 245 | left=IsSame(pRoot1->left, pRoot2->left); 246 | if(pRoot2->right) 247 | right=IsSame(pRoot1->right, pRoot2->right); 248 | return left&&right; 249 | } 250 | bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) { 251 | if(!pRoot2||!pRoot1) 252 | return false; 253 | if(IsSame(pRoot1,pRoot2)) 254 | return true; 255 | if(HasSubtree(pRoot1->left,pRoot2)||HasSubtree(pRoot1->right,pRoot2)) 256 | return true; 257 | else 258 | return false; 259 | } 260 | }; 261 | ``` 262 | 263 |
264 | ↥ Back To Top 265 |
266 | 267 | 268 | ### 6. 二叉搜索树的后序遍历序列 269 | 270 | 描述: 271 | ``` 272 | 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。 273 | 以上转换过程如下图所示: 274 | ``` 275 | ![img](https://uploadfiles.nowcoder.com/images/20220423/115230192_1650720965324/EFE7953D46B926AFF99D8C8A97A56E1E) 276 | ```cpp 277 | class Solution { 278 | public: 279 | bool VerifySquenceOfBST(vector sequence) { 280 | if(sequence.size()==0) 281 | return false; 282 | stack s; 283 | int root=10000; 284 | for(int i=sequence.size()-1;i>=0;--i){ 285 | if(sequence[i]>root) return false; 286 | while(!s.empty()&&s.top()>sequence[i]){ 287 | root=s.top(); 288 | s.pop(); 289 | } 290 | s.push(sequence[i]); 291 | } 292 | return true; 293 | } 294 | }; 295 | ``` 296 | 297 |
298 | ↥ Back To Top 299 |
300 | 301 | 302 | ### 7. 二叉树中和为某一值的路径(二) 303 | 描述: 304 | ``` 305 | 输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。 306 | 以上转换过程如下图所示: 307 | ``` 308 | ![img](https://uploadfiles.nowcoder.com/images/20220423/115230192_1650725369732/762522CE1B46A13C63969D944D6658DE) 309 | ```cpp 310 | class Solution { 311 | public: 312 | vector> ret; 313 | vector path; 314 | void dfs(TreeNode* root, int number){ 315 | if(root==NULL) return; 316 | path.push_back(root->val); 317 | number -= root->val; 318 | if(root->left==NULL&&root->right==NULL&&number==0){ 319 | ret.push_back(path); 320 | } 321 | dfs(root->left, number); 322 | dfs(root->right, number); 323 | path.pop_back(); 324 | } 325 | vector> FindPath(TreeNode* root,int expectNumber) { 326 | dfs(root, expectNumber); 327 | return ret; 328 | } 329 | }; 330 | ``` 331 | 332 |
333 | ↥ Back To Top 334 |
335 | 336 | 337 | ### 8. 复杂链表的复制 338 | 描述: 339 | ``` 340 | 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 341 | 以上转换过程如下图所示: 342 | ``` 343 | ![img](https://uploadfiles.nowcoder.com/images/20220423/397721558_1650683274480/D83430A7F5827D198AD11AAFBBF96B0C) 344 | ```cpp 345 | 346 | class Solution { 347 | public: 348 | RandomListNode* Clone(RandomListNode* pHead) { 349 | if(pHead==NULL) 350 | return pHead; 351 | RandomListNode *cur=pHead; 352 | while(cur!=NULL){ 353 | RandomListNode *clone=new RandomListNode(cur->label); 354 | clone->next=cur->next; 355 | cur->next=clone; 356 | cur=clone->next; 357 | } 358 | cur=pHead; 359 | RandomListNode *clone=pHead->next; 360 | RandomListNode *res=pHead->next; 361 | while(cur!=NULL){ 362 | if(cur->random==NULL) 363 | clone->random=NULL; 364 | else 365 | clone->random=cur->random->next; 366 | cur=cur->next->next; 367 | if(clone->next!=NULL){ 368 | clone=clone->next->next; 369 | } 370 | } 371 | cur=pHead; 372 | clone=pHead->next; 373 | while(cur!=NULL){ 374 | cur->next=cur->next->next; 375 | cur=cur->next; 376 | if(clone->next !=NULL){ 377 | clone->next=clone->next->next; 378 | clone=clone->next; 379 | } 380 | } 381 | return res; 382 | } 383 | }; 384 | ``` 385 | 386 |
387 | ↥ Back To Top 388 |
389 | 390 | 391 | ### 9. 字符串的排列 392 | 描述: 393 | ``` 394 | 输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。 395 | 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 396 | 以上转换过程如下图所示: 397 | ``` 398 | ![img](https://uploadfiles.nowcoder.com/images/20220330/397721558_1648641493550/179947EE9CF9D1C561931DFE816CDAC6) 399 | ```cpp 400 | 401 | class Solution { 402 | public: 403 | void recursion(vector &res, string &str, string &temp, vector &vis){ 404 | if(temp.length()==str.length()){ 405 | res.push_back(temp); 406 | return; 407 | } 408 | for(int i=0;i0&&str[i-1]==str[i]&&!vis[i-1]) 412 | continue; 413 | vis[i]=1; 414 | temp.push_back(str[i]); 415 | recursion(res, str, temp, vis); 416 | vis[i]=0; 417 | temp.pop_back(); 418 | } 419 | } 420 | vector Permutation(string str) { 421 | sort(str.begin(),str.end()); 422 | vector res; 423 | vector vis(str.size(), 0); 424 | string temp; 425 | recursion(res, str, temp, vis); 426 | return res; 427 | } 428 | }; 429 | ``` 430 | 431 |
432 | ↥ Back To Top 433 |
434 | 435 | 436 | ### 10. 数组的逆序对 437 | 描述: 438 | ``` 439 | 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007 440 | ``` 441 | ![img](https://uploadfiles.nowcoder.com/images/20220330/397721558_1648641493550/179947EE9CF9D1C561931DFE816CDAC6) 442 | ```cpp 443 | 444 | class Solution { 445 | public: 446 | int mod=1000000007; 447 | int mergeSort(int left,int right,vector& data,vector&temp){ 448 | if(left>=right) 449 | return 0; 450 | int mid=(left+right)/2; 451 | int res=mergeSort(left, mid, data, temp)+mergeSort(mid+1, right, data, temp); 452 | res%=mod; 453 | int i=left,j=mid+1; 454 | for(int k=left;k<=right;k++) 455 | temp[k]=data[k]; 456 | for(int k=left;k<=right;k++){ 457 | if(i==mid+1) 458 | data[k]=temp[j++]; 459 | else if(j==right+1||temp[i]<=temp[j]) 460 | data[k]=temp[i++]; 461 | else{ 462 | data[k]=temp[j++]; 463 | res+=mid-i+1; 464 | } 465 | } 466 | return res%mod; 467 | 468 | } 469 | int InversePairs(vector data) { 470 | int n=data.size(); 471 | vector res(n); 472 | return mergeSort(0, n-1, data, res); 473 | } 474 | }; 475 | ``` 476 | 477 |
478 | ↥ Back To Top 479 |
480 | 481 | 482 | ### 11. 二叉搜索树的第k个节点 483 | 描述: 484 | ``` 485 | 给定一棵结点数为n 二叉搜索树,请找出其中的第 k 小的TreeNode结点值。 486 | 1.返回第k小的节点值即可 487 | 2.不能查找的情况,如二叉树为空,则返回-1,或者k大于n等等,也返回-1 488 | 3.保证n个节点的值不一样 489 | ``` 490 | ![img](https://uploadfiles.nowcoder.com/images/20211117/392807_1637120852509/F732B49BA33ECC72FF97FF7BDE2ACF69) 491 | ```cpp 492 | 493 | class Solution { 494 | public: 495 | TreeNode *res=NULL; 496 | int count =0; 497 | void midOrder(TreeNode* root, int k){ 498 | if(root==NULL||count>k) 499 | return; 500 | midOrder(root->left, k); 501 | count++; 502 | if(count==k) //是不是root, 不足则继续看右子树 503 | res=root; 504 | midOrder(root->right, k); 505 | } 506 | int KthNode(TreeNode* proot, int k) { 507 | midOrder(proot, k); 508 | if(res) 509 | return res->val; 510 | else 511 | return -1; 512 | } 513 | }; 514 | ``` 515 | 516 |
517 | ↥ Back To Top 518 |
519 | 520 | 521 | ### 12. 连续子数组的最大和 522 | 描述: 523 | ``` 524 | 输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组 525 | 如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个 526 | 不存在空数组 527 | 返回的数组不计入空间复杂度计算 528 | ``` 529 | ![img](https://uploadfiles.nowcoder.com/images/20211204/397721558_1638607774484/83C9DB1D7BB98AFD16716153916EAC03) 530 | ```cpp 531 | 532 | class Solution { 533 | public: 534 | vector FindGreatestSumOfSubArray(vector& array) { 535 | // write code here 536 | vector dp(array.size(), 0); 537 | vector res; 538 | dp[0]=array[0]; 539 | int maxsum=dp[0]; 540 | int left=0, right=0; 541 | int resl=0, resr=0; 542 | for(int i=1;imaxsum||dp[i]==maxsum&&(right-left+1)>(resr-resl+1)){ 548 | maxsum=dp[i]; 549 | resl=left; 550 | resr=right; 551 | } 552 | } 553 | for(int i=resl; i<=resr;i++) 554 | res.push_back(array[i]); 555 | return res; 556 | } 557 | }; 558 | ``` 559 | 560 |
561 | ↥ Back To Top 562 |
563 | 564 | 565 | ### 13. 在二叉树中找到两个节点的最近公共祖先 566 | 描述: 567 | ``` 568 | 给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。 569 | ``` 570 | ![img](https://uploadfiles.nowcoder.com/images/20211014/423483716_1634206667843/D2B5CA33BD970F64A6301FA75AE2EB22) 571 | ```cpp 572 | 573 | /** 574 | * struct TreeNode { 575 | * int val; 576 | * struct TreeNode *left; 577 | * struct TreeNode *right; 578 | * }; 579 | */ 580 | 581 | class Solution { 582 | public: 583 | /** 584 | * 585 | * @param root TreeNode类 586 | * @param o1 int整型 587 | * @param o2 int整型 588 | * @return int整型 589 | */ 590 | TreeNode* LCA(TreeNode* root, int o1, int o2){ 591 | if(!root) return NULL; 592 | if(root->val==o1|| root->val==o2) return root; 593 | 594 | TreeNode* ln=LCA(root->left, o1, o2); 595 | TreeNode* rn=LCA(root->right, o1,o2); 596 | if(!ln) return rn; 597 | if(!rn) return ln; 598 | return root; 599 | } 600 | int lowestCommonAncestor(TreeNode* root, int o1, int o2) { 601 | // write code here 602 | TreeNode* lca=LCA(root, o1,o2); 603 | return lca->val; 604 | } 605 | }; 606 | ``` 607 | 608 |
609 | ↥ Back To Top 610 |
611 | 612 | 613 | ### 14. 冒泡排序 614 | 描述: 615 | ``` 616 | 冒泡排序,比较相邻的两个数据,将最大的数据在第一轮中移到末尾,第二大在第二轮移到倒数第二,总共进行n-1轮。 617 | ``` 618 | ![img]() 619 | ```cpp 620 | class Solution { 621 | public: 622 | void Bubble(int a[], int n){ 623 | for(int i=0; ia[j+1]){ 626 | int temp=a[j]; 627 | a[j]=a[j+1]; 628 | a[j+1]=temp; 629 | } 630 | } 631 | } 632 | } 633 | ``` 634 | 635 |
636 | ↥ Back To Top 637 |
638 | 639 | ### 15. 滑动窗口的最大值 640 | 描述: 641 | ``` 642 | 给定一个长度为 n 的数组 nums 和滑动窗口的大小 size ,找出所有滑动窗口里数值的最大值。 643 | ``` 644 | ![img]() 645 | ```cpp 646 | class Solution { 647 | public: 648 | vector maxInWindows(const vector& nums, int size) { 649 | vector ret; 650 | if(nums.size()==0||size<1||nums.size() dq; 653 | for(int i=0; i=size){ 662 | ret.push_back(nums[dq.front()]); 663 | } 664 | } 665 | return ret; 666 | } 667 | }; 668 | ``` 669 | 670 |
671 | ↥ Back To Top 672 |
673 | --------------------------------------------------------------------------------