├── .gitignore ├── Leetcode 剑指offer 面试题库 ├── 面试题03. 数组中重复的数字.cpp ├── 面试题04. 二维数组中的查找.cpp ├── 面试题05. 替换空格.cpp ├── 面试题06. 从尾到头打印链表.cpp ├── 面试题07. 重建二叉树.cpp ├── 面试题08. 二叉树的下一个结点.cpp ├── 面试题09. 用两个栈实现队列.cpp ├── 面试题10- I. 斐波那契数列.cpp ├── 面试题10- III. 青蛙跳台阶问题.cpp ├── 面试题10-II. 矩形覆盖.cpp ├── 面试题10.IIII 变态跳台阶.cpp ├── 面试题11. 旋转数组的最小数字.cpp ├── 面试题12. 矩阵中的路径.cpp ├── 面试题12. 矩阵中的路径.py ├── 面试题13. 机器人的运动范围.cpp ├── 面试题14- I. 剪绳子.py ├── 面试题15. 二进制中1的个数.cpp ├── 面试题16. 数值的整数次方.cpp ├── 面试题17. 打印从1到最大的n位数.cpp ├── 面试题18. 删除链表的节点.cpp ├── 面试题19. 正则表达式匹配.cpp ├── 面试题21. 调整数组顺序使奇数位于偶数前面.cpp ├── 面试题22. 链表中倒数第k个节点.cpp ├── 面试题24. 反转链表.cpp ├── 面试题25. 合并两个排序的链表.cpp ├── 面试题26. 树的子结构.cpp ├── 面试题27. 二叉树的镜像.cpp ├── 面试题28. 对称的二叉树.cpp ├── 面试题29. 顺时针打印矩阵.cpp ├── 面试题30. 包含min函数的栈.cpp ├── 面试题31. 栈的压入、弹出序列.cpp ├── 面试题32 - I. 从上到下打印二叉树.cpp ├── 面试题32 - II. 从上到下打印二叉树 II.cpp ├── 面试题32 - III. 从上到下打印二叉树 III.cpp ├── 面试题33. 二叉搜索树的后序遍历序列.cpp ├── 面试题34. 二叉树中和为某一值的路径.cpp ├── 面试题35. 复杂链表的复制.cpp ├── 面试题36. 二叉搜索树与双向链表.cpp ├── 面试题37. 序列化二叉树.cpp ├── 面试题38. 字符串的排列.cpp ├── 面试题39. 数组中出现次数超过一半的数字.cpp ├── 面试题40. 最小的k个数.cpp ├── 面试题42. 连续子数组的最大和.cpp ├── 面试题44. 数字序列中某一位的数字.cpp ├── 面试题45. 把数组排成最小的数.cpp ├── 面试题47. 礼物的最大价值.cpp ├── 面试题48. 最长不含重复字符的子字符串.cpp ├── 面试题49. 丑数.cpp ├── 面试题50. 第一个只出现一次的字符.cpp ├── 面试题51. 数组中的逆序对.cpp ├── 面试题52. 两个链表的第一个公共节点.cpp ├── 面试题53 - I. 在排序数组中查找数字 I.cpp ├── 面试题53 - II. 0~n-1中缺失的数字.cpp ├── 面试题54. 二叉搜索树的第k大节点.cpp ├── 面试题55 - I. 二叉树的深度.cpp ├── 面试题55 - II. 平衡二叉树.cpp ├── 面试题56 - I. 数组中数字出现的次数.cpp ├── 面试题56 - II. 数组中数字出现的次数 II.cpp ├── 面试题57 - II. 和为s的连续正数序列.cpp ├── 面试题57. 和为s的两个数字.cpp ├── 面试题58 - I. 翻转单词顺序.cpp ├── 面试题58 - II. 左旋转字符串.cpp ├── 面试题59 - I. 滑动窗口的最大值.cpp ├── 面试题59 - II. 队列的最大值.cpp ├── 面试题60. n个骰子的点数.cpp ├── 面试题61. 扑克牌中的顺子.cpp ├── 面试题62. 圆圈中最后剩下的数字.cpp ├── 面试题63. 股票的最大利润.cpp ├── 面试题64. 求1+2+…+n.cpp ├── 面试题65. 不用加减乘除做加法.cpp ├── 面试题66. 构建乘积数组.cpp ├── 面试题67. 把字符串转换成整数.cpp ├── 面试题68 - I. 二叉搜索树的最近公共祖先.cpp └── 面试题68 - II. 二叉树的最近公共祖先.cpp ├── Leetcode 程序员面试金典 ├── 面试题 01.06. 字符串压缩.cpp └── 面试题 02.02. 返回倒数第 k 个节点.cpp ├── My-Leetcode ├── Cpp │ ├── 10. 正则表达式匹配【递归】.cpp │ ├── 102. 二叉树的层次遍历【BFS】.cpp │ ├── 106. 从中序与后序遍历序列构造二叉树【二叉树 递归】.cpp │ ├── 120. 三角形最小路径和【动态规划】.cpp │ ├── 122. 买卖股票的最佳时机 II【贪心算法】.cpp │ ├── 126.单词接龙【图】.cpp │ ├── 133. 克隆图【图】.cpp │ ├── 134. 加油站【贪心算法】.cpp │ ├── 135. 分发糖果【贪心算法】.cpp │ ├── 136. 只出现一次的数字1【位运算】.cpp │ ├── 144. 二叉树的前序遍历【递归 迭代】.cpp │ ├── 145. 二叉树的后序遍历【递归 迭代】.cpp │ ├── 146. LRU缓存机制【哈希链表】.cpp │ ├── 169. 求众数【摩尔投票法】.cpp │ ├── 200. 岛屿数量【深度优先搜索】.cpp │ ├── 206. 反转链表【链表】.cpp │ ├── 207. 课程表【广度优先搜索实现拓扑排序】.cpp │ ├── 207. 课程表【深度优先搜索实现拓扑排序】.cpp │ ├── 21. 合并两个有序链表【链表】.cpp │ ├── 210. 课程表 II【广度优先搜索+拓扑排序】.cpp │ ├── 215. 数组中的第K个最大元素【堆】.cpp │ ├── 226. 翻转二叉树【二叉树】.cpp │ ├── 230. 二叉搜索树中第K小的元素【二叉树】.cpp │ ├── 240. 搜索二维矩阵 II【二分查找法】.cpp │ ├── 263. 丑数【数学】.cpp │ ├── 264. 丑数 II【三指针】.cpp │ ├── 297. 二叉树的序列化与反序列化.cpp │ ├── 33. 搜索旋转排序数组【查找】.cpp │ ├── 36. 有效的数独【哈希表】.cpp │ ├── 37. 解数独【回溯法】.cpp │ ├── 39. 组合总和【递归】.cpp │ ├── 40. 组合总和 II【递归】.cpp │ ├── 42. 接雨水【数组 双指针】.cpp │ ├── 45. 跳跃游戏 II【贪心算法】.cpp │ ├── 455. 分发饼干【贪心算法】.cpp │ ├── 46. 全排列【递归】.cpp │ ├── 47. 全排列 II【递归】.cpp │ ├── 53. 最大子序和【动态规划 分治法】.cpp │ ├── 54. 螺旋矩阵【数组】.cpp │ ├── 55. 跳跃游戏【贪心算法】.cpp │ ├── 62. 不同路径【动态规划】.cpp │ ├── 63. 不同路径II【动态规划】.cpp │ ├── 64. 最小路径和【动态规划】.cpp │ ├── 674. 最长连续递增序列【动态规划】.cpp │ ├── 704. 二分查找【二分查找法】.cpp │ ├── 712. 两个字符串的最小ASCII删除和【动态规划】.cpp │ ├── 758. 字符串中的加粗单词【字符串】.cpp │ ├── 785. 判断二分图【深度优先搜索+图】.cpp │ ├── 787. K 站中转内最便宜的航班【bellman-ford】.cpp │ ├── 79. 单词搜索【回溯法】.cpp │ ├── 81. 搜索旋转排序数组 II【查找】.cpp │ ├── 87. 扰乱字符串【动态规划】.cpp │ ├── 87. 扰乱字符串【递归】.cpp │ ├── 88. 合并两个有序数组.cpp │ ├── 91. 解码方法【动态规划】.cpp │ ├── 94. 二叉树的中序遍历【递归 迭代】.cpp │ ├── 95. 不同的二叉搜索树 II【递归+深度优先搜索+动态规划】.cpp │ ├── 973. 最接近原点的 K 个点【堆+优先队列】.cpp │ └── headfile.h ├── Go │ ├── 1.两数之和【哈希】.go │ ├── 10.正则表达式匹配.go │ ├── 102.二叉树的层序遍历.go │ ├── 1028.从先序遍历还原二叉树.go │ ├── 103.二叉树的锯齿形层序遍历.go │ ├── 107.二叉树的层序遍历-ii.go │ ├── 1143.最长公共子序列.go │ ├── 121.买卖股票的最佳时机.go │ ├── 14.最长公共前缀.go │ ├── 141.环形链表.go │ ├── 146.lru-缓存机制.go │ ├── 15.三数之和.go │ ├── 151.翻转字符串里的单词.go │ ├── 169.多数元素.go │ ├── 19.删除链表的倒数第-n-个结点.go │ ├── 195.第十行.go │ ├── 2.两数相加.go │ ├── 20.有效的括号.go │ ├── 206.反转链表.go │ ├── 208.实现-trie-前缀树.go │ ├── 21.合并两个有序链表.go │ ├── 222.完全二叉树的节点个数.go │ ├── 226.翻转二叉树.go │ ├── 23.合并k个升序链表.go │ ├── 232.用栈实现队列.go │ ├── 235.二叉搜索树的最近公共祖先.go │ ├── 236.二叉树的最近公共祖先.go │ ├── 237.删除链表中的节点.go │ ├── 239.滑动窗口最大值.go │ ├── 24.两两交换链表中的节点.go │ ├── 25.k-个一组翻转链表.go │ ├── 258.各位相加.go │ ├── 26.删除有序数组中的重复项.go │ ├── 292.nim-游戏.go │ ├── 297.二叉树的序列化与反序列化.go │ ├── 3.无重复字符的最长子串.go │ ├── 33.搜索旋转排序数组.go │ ├── 342.4-的幂.go │ ├── 347.前-k-个高频元素.go │ ├── 380.o-1-时间插入、删除和获取随机元素.go │ ├── 4.寻找两个正序数组的中位数.go │ ├── 402.移掉k位数字.go │ ├── 42.接雨水.go │ ├── 457.环形数组是否存在循环.go │ ├── 5.最长回文子串.go │ ├── 53.最大子序和.go │ ├── 55.跳跃游戏.go │ ├── 589.n-叉树的前序遍历.go │ ├── 590.n-叉树的后序遍历.go │ ├── 6.z-字形变换.go │ ├── 617.合并二叉树.go │ ├── 662.二叉树最大宽度.go │ ├── 692.前k个高频单词.go │ ├── 695.岛屿的最大面积.go │ ├── 7.整数反转.go │ ├── 70.爬楼梯.go │ ├── 700.二叉搜索树中的搜索.go │ ├── 701.二叉搜索树中的插入操作.go │ ├── 704.二分查找.go │ ├── 725.分隔链表.go │ ├── 9.回文数.go │ ├── 912.排序数组.go │ └── 98.验证二叉搜索树.go ├── Python │ ├── 11. 盛最多水的容器【双指针】.py │ ├── 15. 三数之和【数组 双指针】.py │ ├── 16. 最接近的三数之和【双指针】.py │ ├── 20. 有效的括号【栈】.py │ ├── 53. 最大子数组和【动态规划】.py │ └── 54. 螺旋矩阵【数组】.py └── SQL │ └── 176. 第二高的薪水.sql ├── README.md ├── 数据结构与算法 ├── 动态规划 │ ├── 【树&动态规划】扰乱字符串.cpp │ ├── 广州没有雪-2 .cpp │ ├── 最长回文子串.cpp │ ├── 跳跃游戏.cpp │ └── 跳跃游戏II.cpp ├── 图 │ ├── dijkstra算法.cpp │ ├── 【BFS】Knight Moves .cpp │ ├── 【dfs】The Longest Path.cpp │ ├── 【dijkstra】培根数Bacon Number.cpp │ ├── 【优先队列+拓扑排序】Ordering Tasks .cpp │ ├── 【最小生成树】prim算法.cpp │ ├── 【邻接表+bfs】Oil Deposits .cpp │ ├── 克隆图.cpp │ ├── 返回无向图度数序列.cpp │ └── 邻接矩阵实现图.cpp ├── 堆 │ └── 优先队列的cmp参数使用.cpp ├── 字符串 │ ├── Mystring.cpp │ ├── Z字形变换.cpp │ ├── [KMP]字符串子串.cpp │ ├── [STL Pair]Counting Frequencies of Words .cpp │ ├── 无重复字符的最长子串.cpp │ └── 读取文本计词数.cpp ├── 排序 │ ├── 合并K个排序链表.cpp │ ├── 合并序列.cpp │ ├── 排序算法 │ │ ├── 基数排序.cpp │ │ ├── 堆排序.cpp │ │ ├── 希尔排序.cpp │ │ ├── 归并排序.cpp │ │ ├── 快速排序.cpp │ │ ├── 插入排序.cpp │ │ └── 选择排序.cpp │ ├── 最大数.cpp │ └── 链表的插入排序.cpp ├── 查找 │ ├── Message flood.cpp │ ├── 【map】两数之和.cpp │ ├── 哈希表.cpp │ ├── 寻找两个有序数组的中位数.cpp │ ├── 搜索旋转排序数组.cpp │ ├── 搜索旋转排序数组II.cpp │ └── 检查快速排序划分的正确性.cpp ├── 栈 │ ├── Remove Duplicate Letters.cpp │ ├── 下一个更大元素 I.cpp │ ├── 下一个更大元素 II.cpp │ ├── 括号匹配算法.cpp │ ├── 火车出栈问题.cpp │ └── 验证栈的序列.cpp ├── 树 │ ├── Width of Binary Trees.cpp │ ├── 【深度优先搜索】路径总和.cpp │ ├── 二叉查找树的实现.cpp │ ├── 二叉树的层次遍历 II.cpp │ ├── 二叉树的高度.cpp │ ├── 前序遍历和中序遍历建立二叉树.cpp │ ├── 哈夫曼编码 │ │ ├── Decoding │ │ │ ├── ReadMe.txt │ │ │ ├── huffmanCoding inputfile.txt │ │ │ ├── huffmanCoding outputfile.txt │ │ │ ├── huffmanDeCoding inputfile.txt │ │ │ ├── huffmanDeCoding outputfile.txt │ │ │ └── 源.cpp │ │ ├── coding │ │ │ ├── ReadMe.txt │ │ │ ├── huffmanCoding inputfile.txt │ │ │ ├── huffmanCoding outputfile.txt │ │ │ └── 源.cpp │ │ ├── huffmanCoding inputfile.txt │ │ ├── huffmanCoding outputfile.txt │ │ ├── huffmanDeCoding inputfile.txt │ │ └── huffmanDeCoding outputfile.txt │ ├── 完全二叉树的节点个数.cpp │ └── 非递归中序遍历.cpp ├── 递归 │ ├── Fractal.cpp │ ├── 【全排列】交换字符.cpp │ └── 【递归】八皇后问题判定.cpp └── 链表 │ ├── ArrayList, version 2 .cpp │ ├── Copy Linked Lists .cpp │ ├── Set Intersection (2) .cpp │ ├── Set Intersection.cpp │ ├── [全排列]数组链表.cpp │ ├── 【数组链表】猴子选大王.cpp │ └── 两数相加.cpp ├── 洛谷 ├── P1726 上白泽慧音【强连通分量模板 kosaraju算法】.cpp ├── P2704 草地排水【网络流模板 EK算法】.cpp └── headfile.h └── 面经 ├── 2020 春招 广州字节 飞书后台凉面.md ├── 2020春招 字节 广州 面经.pdf ├── 2020春招 字节跳动 深圳后端开发实习生.md ├── 2020春招 腾讯 深圳后台 pcg 面经.md ├── 2020春招 腾讯 深圳后台 qq音乐 面经.md ├── 2020春招 腾讯TEG.md ├── 2021 春招 广州字节 清北教育后台.md ├── 2021 春招 广州微信 后台.md ├── 2021 秋招 广州字节 后台开发 凉面.md ├── 2023 秋招 深圳腾讯 微信客户端.md ├── 2023 腾讯wxg微信支付 凉面 ZQQ.md └── 面试智力题.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/* 2 | *.exe 3 | test/* -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题03. 数组中重复的数字.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int findRepeatNumber(vector& nums) { 6 | int *bucket = new int[nums.size()]{0}; 7 | for(int i = 0;i1) 11 | { 12 | return nums[i]; 13 | } 14 | } 15 | return -1; 16 | } 17 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题04. 二维数组中的查找.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool findNumberIn2DArray(vector>& matrix, int target) { 6 | if(matrix.size()==0) return false; 7 | int m = matrix.size(); 8 | int n = matrix[0].size(); 9 | 10 | // 定义开始位置 11 | int x = m-1; 12 | int y = 0; 13 | while(x>=0 && y reversePrint(ListNode* head) { 12 | vectorres; 13 | helper(head,res); 14 | return res; 15 | } 16 | void helper(ListNode* head,vector& res){ 17 | if(head){ 18 | if(head->next){ 19 | helper(head->next,res); 20 | } 21 | res.push_back(head->val); 22 | } 23 | return ; 24 | } 25 | 26 | //方法2 使用栈 27 | vector reversePrint2(ListNode* head) { 28 | vectorres; 29 | stacksk; 30 | while(head){ 31 | sk.push(head->val); 32 | head=head->next; 33 | } 34 | while(!sk.empty()){ 35 | res.push_back(sk.top()); 36 | sk.pop(); 37 | } 38 | return res; 39 | 40 | } 41 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题07. 重建二叉树.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | TreeNode* buildTree(vector& preorder, vector& inorder) { 13 | int lenth=preorder.size(); 14 | if(lenth<=0) return NULL; 15 | int startPre=0,endPre=lenth-1,startIn=0,endIn=lenth-1; 16 | return constructTree(startPre,endPre,startIn,endIn,preorder, inorder); 17 | } 18 | 19 | TreeNode* constructTree(int startPre,int endPre,int startIn,int endIn,vector& preorder, vector& inorder) 20 | { 21 | if(startPre>endPre) 22 | return NULL; 23 | TreeNode* root=new TreeNode(preorder[startPre]); 24 | int leftTree=0; 25 | while(inorder[startIn+leftTree]!=preorder[startPre]) 26 | { 27 | leftTree++; 28 | } 29 | // 中序中根的左边是左子树的结点,有多少个,对应的前序接下来多少个结点是在左子树 30 | root->left=constructTree(startPre+1,startPre+leftTree,startIn,startIn+leftTree-1,preorder, inorder); 31 | root->right=constructTree(startPre+leftTree+1,endPre,startIn+leftTree+1,endIn,preorder, inorder); 32 | return root; 33 | } 34 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题08. 二叉树的下一个结点.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | //牛客网:https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github 4 | 5 | struct TreeLinkNode { 6 | int val; 7 | struct TreeLinkNode *left; 8 | struct TreeLinkNode *right; 9 | struct TreeLinkNode *next; 10 | TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) { 11 | 12 | } 13 | }; 14 | 15 | class Solution { 16 | public: 17 | TreeLinkNode* GetNext(TreeLinkNode* pNode) 18 | { 19 | if(pNode == NULL) 20 | return NULL; 21 | // 如果当前结点没有右结点,则要向上找 第一个左子树包含当前结点的结点 22 | if(pNode->right == NULL) 23 | { 24 | while(pNode->next!=NULL) 25 | { 26 | TreeLinkNode* par = pNode->next; 27 | if(par->left == pNode) 28 | return par; 29 | pNode = par; 30 | } 31 | return NULL; 32 | } 33 | // 如果存在右结点,一直找到右结点的最左结点 34 | TreeLinkNode* cur = pNode->right; 35 | while(cur->left) 36 | { 37 | cur = cur->left; 38 | } 39 | return cur; 40 | } 41 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题09. 用两个栈实现队列.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | class CQueue { 4 | public: 5 | CQueue() { 6 | } 7 | 8 | void appendTail(int value) { 9 | if(mysta1.empty())// 如果栈1是空的,说明栈2不是空的,把栈2倒过来 10 | { 11 | while(!mysta2.empty()) 12 | { 13 | int tmp = mysta2.top(); 14 | mysta1.push(tmp); 15 | mysta2.pop(); 16 | } 17 | } 18 | mysta1.push(value); 19 | } 20 | 21 | int deleteHead() { 22 | if(mysta2.empty())// 同上 23 | { 24 | while(!mysta1.empty()) 25 | { 26 | int tmp = mysta1.top(); 27 | mysta2.push(tmp); 28 | mysta1.pop(); 29 | } 30 | } 31 | if(mysta2.empty()) 32 | return -1; 33 | int res = mysta2.top(); 34 | mysta2.pop(); 35 | return res; 36 | } 37 | private: 38 | stack mysta1; // 1号栈是队尾在栈顶 39 | stack mysta2; // 2号栈是队头在栈顶 40 | }; 41 | 42 | /** 43 | * Your CQueue object will be instantiated and called as such: 44 | * CQueue* obj = new CQueue(); 45 | * obj->appendTail(value); 46 | * int param_2 = obj->deleteHead(); 47 | */ -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题10- I. 斐波那契数列.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int fib(int n) { 4 | if(n==0) return 0; 5 | if(n==1) return 1; 6 | int* contain = new int[n+1]; 7 | contain[0] = 0; 8 | contain[1] = 1; 9 | for(int i = 2;i &numbers) { 6 | int size = numbers.size(); 7 | if (size == 0) { 8 | return 0; 9 | } 10 | 11 | int left = 0; 12 | int right = size - 1; 13 | 14 | while (left < right) { 15 | int mid = left + (right - left) / 2; // 向下取整 16 | // int mid = left + ((right - left) >> 1); 17 | if (numbers[mid] > numbers[right]) { 18 | // [3, 4, 5, 1, 2],mid 以及 mid 的左边一定不是最小数字 19 | // 下一轮搜索区间是 [mid + 1, right] 20 | left = mid + 1; 21 | } else if (numbers[mid] == numbers[right]) { 22 | // 只能把 right 排除掉,下一轮搜索区间是 [left, right - 1] 23 | right--; 24 | } else { 25 | // 此时 numbers[mid] < numbers[right] 26 | // mid 的右边一定不是最小数字,mid 有可能是,下一轮搜索区间是 [left, mid] 27 | right = mid; 28 | } 29 | } 30 | return numbers[left]; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题12. 矩阵中的路径.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool exist(vector>& board, string word) { 6 | if(board.size() == 0) return false; 7 | for (int i=0;i>& board, string& word, int i,int j,int length){ 18 | if(i>=board.size()||j>=board[0].size()||i<0||j<0||length>=word.size()||word[length]!=board[i][j]){ 19 | return false; 20 | } 21 | if(length==word.size()-1&&word[length]==board[i][j]){ 22 | return true; 23 | } 24 | char temp=board[i][j]; 25 | board[i][j]='0'; 26 | bool flag=dfs(board,word,i,j+1,length+1)||dfs(board,word,i,j-1,length+1)||dfs(board,word,i+1,j,length+1)||dfs(board,word,i-1,j,length+1); 27 | board[i][j]=temp; 28 | return flag; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题12. 矩阵中的路径.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def exist(self, board: List[List[str]], word: str) -> bool: 3 | def dfs(i, j, k): 4 | if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: return False 5 | if k == len(word) - 1: return True 6 | tmp, board[i][j] = board[i][j], '/' 7 | res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1) 8 | board[i][j] = tmp 9 | return res 10 | 11 | for i in range(len(board)): 12 | for j in range(len(board[0])): 13 | if dfs(i, j, 0): return True 14 | return False 15 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题13. 机器人的运动范围.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int movingCount(int m, int n, int k) { 6 | vector >judge(m,vector(n,0)); 7 | return bfs(0,0,m,n,k,judge); 8 | } 9 | int bfs(int x, int y,int m, int n, int k,vector >&judge) 10 | { 11 | if(!(x>=0 && x=0 && yk) 14 | return 0; 15 | if(judge[x][y]==-1) 16 | return 0; 17 | judge[x][y]=-1; // 标记当前位置为已访问过 18 | return 1 + bfs(x+1,y,m,n,k,judge)+bfs(x,y+1,m,n,k,judge); 19 | } 20 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题14- I. 剪绳子.py: -------------------------------------------------------------------------------- 1 | # 贪心算法,其实也是找规律方法 一般情况下剪的越多值越大 · 2 | class Solution: 3 | def cuttingRope(self, n: int) -> int: 4 | if n <= 3: return n - 1 5 | a, b = n // 3, n % 3 6 | if b == 0: return 3 ** a 7 | if b == 1: return 3 ** (a - 1) * 4 # 3*1<2*2 8 | return 3 ** a * 2 9 | 10 | # 动态规划的方法,对每一个n,遍历所有可能的剪法,剪完剩下的部分分为剪还是不剪,取最大值 11 | class Solution1: 12 | def cuttingRope(self, n: int) -> int: 13 | dp = [0 for _ in range(n + 1)] # dp[0] dp[1]其实没用 14 | dp[2] = 1 # 初始化 15 | res = -1 16 | for i in range(3, n + 1): 17 | for j in range(i): 18 | dp[i] = max(dp[i], max((i - j) * j, j * dp[i - j])) 19 | return dp[n] 20 | 21 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题15. 二进制中1的个数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int hammingWeight(uint32_t n) { 6 | // 一位一位判断是1还是0 7 | int ret = 0; 8 | for (int i = 0; i < 32; i ++) { 9 | if (n & (1 << i)) { 10 | ret ++; 11 | } 12 | } 13 | return ret; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题16. 数值的整数次方.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | //题解:快速幂 6 | double myPow(double base, int n) { 7 | double res=1.0; 8 | int i=n; 9 | while(i){ 10 | if(i&1)res*=base; //i的低位存在,res*x 11 | base*=base; //base扩大为它的平方,因为n要左移一位,所以之后最低位变为base^2 12 | i/=2; //i右移一位 13 | } 14 | return n<0?1/res:res; 15 | } 16 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题17. 打印从1到最大的n位数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector printNumbers(int n) { 6 | vector res; 7 | if (n == 0) return res; 8 | //打印到数组中 9 | for (int i=1,max=pow(10,n);ival != val) 10 | { 11 | pre = cur; 12 | cur = cur->next; 13 | } 14 | if(pre != NULL) // 如果删除的不是第一个节点 15 | pre->next = cur->next; 16 | else 17 | head = head->next; // 如果删除的是第一个节点,head向下移动一个 18 | // delete cur; // 删除当前节点的值 leetcode不要求 19 | return head; 20 | } 21 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题19. 正则表达式匹配.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool isMatch(string s, string p) { 6 | if (p.empty()) return s.empty(); 7 | if (p.size() > 1 && p[1] == '*') { // 如果p的下一个字符是*号 分两种情况 8 | return isMatch(s, p.substr(2)) || (!s.empty() && (s[0] == p[0] || p[0] == '.') && // 第一种:当前对应字符不同,则p去掉前两个继续匹配 9 | isMatch(s.substr(1), p));//第二种:当前对应字符相同,s后移动一个,因为p有*,所以不用管 10 | } 11 | // 如果p的下一个字符不是*号,考虑s为空的情况,然后判断当前字符是否相同,相同的话各自后移一位继续递归 12 | return !s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p.substr(1)); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题21. 调整数组顺序使奇数位于偶数前面.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector exchange(vector& nums) { 6 | // 快速排序的思想 7 | if(nums.size()<=1) return nums; 8 | int left = 0; 9 | int right = nums.size()-1; 10 | int pivot = nums[left]; 11 | while(left 0) 7 | { 8 | count --; 9 | head = head->next; 10 | } 11 | if(head == NULL) return NULL; // 如果链表本身长度小于k,返回空 12 | while(head->next!=NULL) 13 | { 14 | head = head->next; 15 | res = res->next; 16 | } 17 | return res; 18 | } 19 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题24. 反转链表.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct ListNode { 4 | int val; 5 | ListNode *next; 6 | ListNode(int x) : val(x), next(NULL) {} 7 | }; 8 | 9 | class Solution { 10 | public: 11 | ListNode* newhead; 12 | // 递归法实现 13 | ListNode* reverseList(ListNode* head) { 14 | helper(head); 15 | return newhead; 16 | } 17 | ListNode* helper(ListNode* head){ 18 | if(head == NULL) return NULL; 19 | if(head->next == NULL) 20 | { 21 | this->newhead = head; 22 | return head; 23 | } 24 | ListNode* node = helper(head->next); 25 | node->next = head; 26 | head->next = NULL; 27 | return head; 28 | } 29 | }; 30 | 31 | 32 | class Solution2 { 33 | public: 34 | // 用迭代法解决 35 | ListNode* reverseList(ListNode* head) { 36 | ListNode* cur = NULL, *pre = head; 37 | while (pre != NULL) { 38 | ListNode* t = pre->next; 39 | pre->next = cur; 40 | cur = pre; 41 | pre = t; 42 | } 43 | return cur; 44 | } 45 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题25. 合并两个排序的链表.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct ListNode { 4 | int val; 5 | ListNode *next; 6 | ListNode(int x) : val(x), next(NULL) {} 7 | }; 8 | 9 | class Solution { 10 | public: 11 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 12 | ListNode* newptr = new ListNode(-1); 13 | ListNode * cur = newptr; 14 | while(l1!=NULL && l2!=NULL) 15 | { 16 | if(l1->val <= l2->val) 17 | { 18 | // 将l1的元素加入 19 | cur->next = l1; 20 | l1 = l1->next; 21 | } 22 | else 23 | { 24 | // 将l2的元素加入 25 | cur->next = l2; 26 | l2 = l2->next; 27 | } 28 | cur=cur->next; 29 | } 30 | if(l1==NULL) 31 | { 32 | cur->next = l2; 33 | } 34 | else 35 | { 36 | cur->next = l1; 37 | } 38 | return newptr->next; 39 | } 40 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题26. 树的子结构.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | class Solution { 10 | public: 11 | bool isSubStructure(TreeNode* A, TreeNode* B) { 12 | if(B == NULL || A == NULL) return false; 13 | 14 | // 如果A当前值和B的相同,搜索判断二者是否一样 15 | if(A->val == B->val) 16 | { 17 | if(compare(A,B)) 18 | return true; 19 | } 20 | bool left = isSubStructure(A->left,B); 21 | bool right = isSubStructure(A->right,B); 22 | return left||right; 23 | } 24 | bool compare(TreeNode* A, TreeNode* B) // B只探索不为NULL的那边 25 | { 26 | if(A==NULL) 27 | return false; 28 | if(A->val != B->val) 29 | return false; 30 | bool left=true; 31 | bool right=true; 32 | if(B->left != NULL) 33 | left = compare(A->left,B->left); 34 | if(B->right != NULL) 35 | right = compare(A->right,B->right); 36 | return left && right; 37 | } 38 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题27. 二叉树的镜像.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | TreeNode* mirrorTree(TreeNode* root) { 13 | if(root==NULL) return NULL; 14 | TreeNode* node = new TreeNode(root->val); // 构建新的节点 15 | node->left = mirrorTree(root->right); 16 | node->right = mirrorTree(root->left); 17 | return node; 18 | } 19 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题28. 对称的二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | bool isSymmetric(TreeNode* root) { 13 | if(root == NULL) return true; 14 | return helper(root->left,root->right); 15 | } 16 | bool helper(TreeNode* one, TreeNode* two) 17 | { 18 | if(one == NULL && two == NULL) return true; 19 | if(one != NULL && two==NULL || one==NULL && two != NULL) return false; // 有一者为null另一者不为返回false 20 | 21 | // 当两者都不为NULL是递归判断 22 | return (one->val == two->val) && helper(one->left,two->right) && helper(one->right,two->left); 23 | } 24 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题29. 顺时针打印矩阵.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector spiralOrder(vector>& matrix) { 6 | vector res; 7 | if(matrix.size()==0||matrix[0].size()==0) return res; 8 | vector > judge(matrix.size(),vector(matrix[0].size(),0)); // 定义一个判断的矩阵。 9 | 10 | int x= 0,y=0;// 定义起始位置 11 | res.push_back(matrix[x][y]); 12 | judge[0][0] =1; 13 | int flag = 1; 14 | while(flag) 15 | { 16 | flag = 0; //如果都没得走,结束循环 17 | // 先向右走 18 | while(is_legal(x,y+1,judge)) 19 | y++,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 20 | 21 | // 向下走 22 | while(is_legal(x+1,y,judge)) 23 | x++,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 24 | 25 | //向左走 26 | while(is_legal(x,y-1,judge)) 27 | y--,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 28 | 29 | while(is_legal(x-1,y,judge)) 30 | x--,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 31 | } 32 | return res; 33 | } 34 | bool is_legal(int x,int y, vector >& judge) 35 | { 36 | int limit_x = judge.size(); 37 | int limit_y = judge[0].size(); 38 | if(x>=0 && x=0 && y& pushed, vector& popped) { 6 | stack mysta;// 辅助栈 7 | int ptr1 = 0, ptr2 = 0; 8 | while(ptr2 < popped.size()) 9 | { 10 | if(ptr1 levelOrder(TreeNode* root) { 7 | vector res; 8 | if(root == NULL) return res; 9 | queue que; 10 | que.push(root); 11 | while(!que.empty()) 12 | { 13 | TreeNode* cur = que.front(); 14 | res.push_back(cur->val); 15 | que.pop(); 16 | if(cur->left!=NULL) que.push(cur->left); 17 | if(cur->right !=NULL) que.push(cur->right); 18 | } 19 | return res; 20 | } 21 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题32 - II. 从上到下打印二叉树 II.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | vector > levelOrder(TreeNode* root) { 13 | vector > res; 14 | if(root == NULL) return res; 15 | queue que; 16 | que.push(root); 17 | while(!que.empty()) 18 | { 19 | vector subres; 20 | int s = que.size(); // 每一层的大小 21 | for(int i =0;ival); // 加入答案中 25 | que.pop(); 26 | if(cur->left!=NULL) que.push(cur->left); 27 | if(cur->right!=NULL) que.push(cur->right); 28 | } 29 | res.push_back(subres); 30 | } 31 | return res; 32 | } 33 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题33. 二叉搜索树的后序遍历序列.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | //数组最后一个值为 根节点值,进行遍历当值大于根节点时break,说明左子树遍历完毕。第二次循环判断右子树,若其中有值小于根节点值则证明不是后序遍历。 4 | //左右节点往下利用递归实现 5 | class Solution { 6 | public: 7 | bool verifyPostorder(vector& postorder) { 8 | return judge(postorder,0,postorder.size()-1); 9 | } 10 | 11 | bool judge(vector&vec,int left,int right){ 12 | if(left>=right){ 13 | return true; 14 | } 15 | int root=vec[right]; 16 | int i=left; 17 | for(;iroot){ 19 | break; 20 | } 21 | } 22 | int j=i; 23 | for(;j > res; 13 | Solution(){} 14 | 15 | vector> pathSum(TreeNode* root, int sum) { 16 | vector cur; 17 | helper(root,sum,cur,0); 18 | return res; 19 | } 20 | void helper(TreeNode* root,int sum, vector cur, int cur_sum) 21 | { 22 | // 深度优先搜索 23 | // 如果到叶子节点时cur_sum等于target 则成功 24 | if(root == NULL) return; 25 | if(root->left == NULL && root->right == NULL) 26 | { 27 | if(cur_sum+root->val == sum) 28 | { 29 | cur.push_back(root->val); 30 | res.push_back(cur); 31 | } 32 | return; 33 | } 34 | cur.push_back(root->val); // 将当前节点加入cur 35 | helper(root->left, sum, cur, cur_sum+root->val); 36 | helper(root->right, sum, cur, cur_sum+root->val); 37 | } 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题36. 二叉搜索树与双向链表.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Node { 4 | public: 5 | int val; 6 | Node* left; 7 | Node* right; 8 | 9 | Node() {} 10 | 11 | Node(int _val) { 12 | val = _val; 13 | left = NULL; 14 | right = NULL; 15 | } 16 | 17 | Node(int _val, Node* _left, Node* _right) { 18 | val = _val; 19 | left = _left; 20 | right = _right; 21 | } 22 | }; 23 | 24 | class Solution { 25 | public: 26 | Node* pre; // 标记上一个节点 27 | Node* first; // 标记第一个节点 28 | Solution():pre(NULL){} 29 | 30 | Node* treeToDoublyList(Node* root) { 31 | if(root == NULL) return NULL; 32 | helper(root); 33 | first->left = pre; 34 | pre->right = first; 35 | return first; 36 | } 37 | void helper(Node* root) 38 | { 39 | if(root == NULL) 40 | return; 41 | if(pre == NULL && root->left == NULL) 42 | first = root; 43 | 44 | // 中序遍历,每次遍历到一个点就和pre连接起来 45 | helper(root->left); 46 | root->left = pre; // 左指针指向前驱 47 | if(pre != NULL) 48 | pre->right = root; //pre的右指针指向后继 49 | pre = root; // 更新上一个节点 50 | helper(root->right); 51 | } 52 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题38. 字符串的排列.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector permutation(string s) { 6 | vector res; 7 | helper(s,0,res); 8 | return res; 9 | } 10 | void helper(string s,int index , vector &res) 11 | { 12 | if(index == s.size()) 13 | { 14 | res.push_back(s); 15 | return; 16 | } 17 | vector judge(128,0); // 用来判断这个字符是否被使用过 18 | for(int i =index;i& nums) { 6 | // 摩尔投票法 7 | int count = 0; // 记录当前数 8 | int cur; // 当前数 9 | for(auto i : nums) 10 | { 11 | if(count == 0) 12 | cur = i, count++; 13 | else if(i!=cur) 14 | count--; 15 | else if(i==cur) 16 | count++; 17 | } 18 | return cur; 19 | } 20 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题40. 最小的k个数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | // 使用堆排序的方法 6 | vector getLeastNumbers(vector& arr, int k) { 7 | vector res; 8 | if(arr.size()==0) return res; 9 | int length = arr.size()-1; 10 | buildMaxHeap(arr,length); // 先构建小顶堆 11 | 12 | // 使用小顶堆选出前k个元素 13 | while(k--) 14 | { 15 | res.push_back(arr[0]); 16 | swap(arr[0], arr[length]); // 和最后一个位置的数字交换 17 | // 重新构建小顶堆 18 | MaxHeap(arr, 0, --length); 19 | } 20 | return res; 21 | } 22 | 23 | void MaxHeap(vector& a,int i,int high)//更新某个节点满足最大堆 24 | //a为要排序数组,i为要排序的节点,high为数组要被维护的最大下标 25 | { 26 | int l = 2*i+1; 27 | int r = 2*i+2; 28 | int largest;//三者较大节点下标 29 | int temp; 30 | //找出r l 和 i位置的节点值的最大值 并和i位置交换 31 | if(l<=high && a[l]& a,int length)//将数组建立成一个最大堆 47 | { 48 | for(int i=length/2-1;i>=0;i--) 49 | { 50 | MaxHeap(a,i,length-1); 51 | } 52 | } 53 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题42. 连续子数组的最大和.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int maxSubArray(vector& nums) { 6 | if (nums.size()==0) return 0; 7 | int pre = nums[0]; //上一个数 8 | int cur; 9 | int res = nums[0]; // 最大值 10 | for(int i =1;i=m 说明找到了区间level 也就是level位数的区间内 18 | int diff = (count_sum - n)/level; // 得到大了多少个数 19 | int diff_index = (count_sum - n)%level; // 在这个数中偏移几位 20 | 21 | int target = pow(10, level) - 1 - diff; // 得到第n位所在的数字 22 | while(diff_index--) 23 | target/=10; 24 | return target%10; 25 | } 26 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题45. 把数组排成最小的数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | // 字符串排序算法 7 | string minNumber(vector& nums) { 8 | string res; 9 | sort(nums.begin(),nums.end(),[](int a, int b ){ return to_string(a)+to_string(b)>& grid) { 6 | if(grid.size()==0 || grid[0].size()==0) return 0; // 判断特殊情况单独讨论 7 | int m = grid.size(); 8 | int n = grid[0].size(); 9 | // 定义动态规划数组 10 | vector > dp(m+1, vector(n+1,0));// 定义多一圈,可以减少判断 11 | 12 | for(int i = 1 ;i<=m;i++) 13 | { 14 | for(int j =1;j<=n;j++) 15 | { 16 | dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + grid[i-1][j-1]; 17 | } 18 | } 19 | return dp[m][n]; 20 | } 21 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题48. 最长不含重复字符的子字符串.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int lengthOfLongestSubstring(string s) { 6 | int hash[128]={0}; // 哈希映射上一个这个字符的位置 7 | vector res(1,0); // 动态规划 初始化第一个为0 8 | for(int i=1;i<=s.size();i++) 9 | { 10 | char cur = s[i-1];// 当前的字符 11 | // 找当前字符的上一个位置 12 | int last = hash[int(cur)]; 13 | hash[int(cur)] = i; 14 | // 计算新的连续不重复串的起始位置 15 | int start = max(i-1-res[i-1]+1,last+1); 16 | res.push_back(i-start+1); 17 | } 18 | return *max_element(res.begin(), res.end()); 19 | } 20 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题49. 丑数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int nthUglyNumber(int n) { 6 | if(n==0) return 0; 7 | vector res; // 动态规划的方法 三指针 8 | res.push_back(1);// 1 为丑数 9 | int p=0,q=0,r=0; 10 | while(res.size() mp; 5 | for(auto c:s) mp[c]++; 6 | for(auto c:s){ 7 | if(mp[c]==1) return c; 8 | } 9 | return ' '; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题51. 数组中的逆序对.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int count; // 统计有多少个逆序对 4 | Solution():count(0){} 5 | 6 | int reversePairs(vector& nums) { 7 | if(nums.size()<=1) return 0; 8 | helper(nums,0,nums.size()-1); 9 | return count; 10 | } 11 | // 使用归并排序的方法 12 | void helper(vector& nums, int i, int j) 13 | { 14 | if(i>=j) return; 15 | int mid = (i+j)/2; // 取中间位置的值 16 | 17 | // 递归归并排序 18 | helper(nums,i,mid); 19 | helper(nums,mid+1,j); 20 | 21 | // 合并排序结果,同时统计逆序对数量 22 | int x = i; 23 | int y = mid+1; 24 | vector tmp; 25 | while(x<=mid && y<=j) 26 | { 27 | if(nums[x]<=nums[y])// 如果左边小于右边 不统计逆序对 28 | { 29 | tmp.push_back(nums[x]); 30 | x++; 31 | } 32 | if(nums[x]>nums[y]) // 左边大于右边,统计逆序对 33 | { 34 | tmp.push_back(nums[y]); 35 | count = count + mid-x+1; 36 | y++; 37 | } 38 | } 39 | if(x>mid) // 如果前面的先用完,把后面的全部加入 40 | for(int p = y; p <=j;p++) 41 | tmp.push_back(nums[p]); 42 | else 43 | for(int p = x; p <=mid;p++) 44 | tmp.push_back(nums[p]); 45 | // 将排好序的结果替换进原来的nums中 46 | for(int p =0;pnext : headB; 9 | node2 = node2 != NULL ? node2->next : headA; 10 | } 11 | return node1; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题53 - I. 在排序数组中查找数字 I.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | int search(vector& nums, int target) { 15 | if(nums.size()==0) return 0; 16 | // 先二分查找到对应的值,然后往后搜所有一样的个数 17 | int index = binarysearch(nums,0,nums.size()-1, target); 18 | int count=0; 19 | while(index & nums, int begin ,int end, int target) 27 | { 28 | while(begin=target)// 如果中间大于,目标,向左边搜索 32 | { 33 | end = mid; 34 | continue; 35 | } 36 | else 37 | { 38 | begin = mid+1; 39 | continue; 40 | } 41 | } 42 | if(begin==end) 43 | return begin; 44 | else 45 | return nums.size(); 46 | 47 | } 48 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题53 - II. 0~n-1中缺失的数字.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | // 桶排序方法 6 | int missingNumber1(vector& nums) { 7 | vector res(nums.size()+1, 0); 8 | for(int i =0;i& nums) 17 | { 18 | if(nums.size()==0) return 0; 19 | return bSearch(nums, 0, nums.size()-1); 20 | } 21 | int bSearch(vector& nums, int left, int right){ 22 | if(left == right) 23 | { 24 | if(nums[left] == left) 25 | return left+1; 26 | else 27 | return left; 28 | } 29 | int mid = (left+right)/2; // 获取中间位置下标 向下去整 30 | if(nums[mid] == mid) // 如果 对应位置正确, 向右边搜索 反之向左边搜索 31 | return bSearch(nums,mid+1,right); 32 | else 33 | return bSearch(nums,left,mid); 34 | } 35 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题54. 二叉搜索树的第k大节点.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int res; 4 | Solution():res(0){} 5 | 6 | int kthLargest(TreeNode* root, int k) { 7 | helper(root,k); 8 | return res; 9 | } 10 | void helper(TreeNode * root, int & k) 11 | { 12 | if(k<=0) 13 | return; 14 | 15 | if(root->right !=NULL) helper(root->right,k); 16 | if((--k)==0) // 如果刚好是第k个,直接保存结果 17 | { 18 | cout<val; 19 | res = root->val; 20 | return; 21 | } 22 | if(root->left!=NULL) helper(root->left,k); 23 | } 24 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题55 - I. 二叉树的深度.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | int maxDepth(TreeNode* root) { 13 | int max_h = 0; 14 | dfs(root, max_h); 15 | return max_h; 16 | } 17 | int dfs(TreeNode* root, int& max_h) 18 | { 19 | if(root == NULL) 20 | return 0; 21 | return max(dfs(root->left, max_h),dfs(root->right,max_h))+1; 22 | } 23 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题55 - II. 平衡二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | bool flag = true; 13 | bool isBalanced(TreeNode* root) { 14 | helper(root); 15 | return flag; 16 | } 17 | int helper(TreeNode* root)// 递归,返回左右子树比较深的一者的高度,一旦出现flag已经为flase直接返回 18 | { 19 | if(!flag) return -1; // 直接返回任意数 20 | if(root == NULL) return 0; // 为空的时候返回0 21 | int left_h = helper(root->left); 22 | int right_h = helper(root->right); 23 | if(abs(left_h-right_h)<2) return max(left_h,right_h)+1; // 返回子树高度 24 | else 25 | flag = false,return -1; 26 | } 27 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题56 - I. 数组中数字出现的次数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector singleNumbers(vector& nums) { 6 | // 本题本质上是结合了另外两个位运算题目的思想 7 | // 我们的目标是将nums分为两组,只出现了一次的两个数分别在不同的一组,然后所有相同的数要分在同一组 8 | // 这样只需要对每个组分别用异或就可以的到结果了 9 | // 先对nums进行分组 10 | int all_xor=0; 11 | for(auto num : nums) // 先对所有数进行异或操作 12 | all_xor ^= num; 13 | 14 | //随便选择一位不为0的位,这一位说明只出现1次的两个数在这一位是可以被划分到不同组的的。按照这一位为0或者为1 分组,就可以满足上诉条件 15 | int h =1; 16 | while((h&all_xor)==0) 17 | h = h<<1; 18 | cout< res(2,0); // 定义答案数组,分成两组 20 | for(auto num:nums) // 遍历所有数 按照对应的组进行异或 最后剩下的结果就是答案 21 | { 22 | if((h&num)!=0) 23 | res[1] ^= num; 24 | else 25 | res[0]^=num; 26 | } 27 | return res; 28 | } 29 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题56 - II. 数组中数字出现的次数 II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int singleNumber(vector& nums) { 4 | // 还是使用位运算,一位位的判断是否不止3个一样的,如果不止,则说明res在这个位置上为1 5 | int res = 0; 6 | unsigned int bit = 0; // 当前位,比如第一位就是0000000000001 7 | for(int i =0;i<32;i++) // 遍历32位,一位位判断 8 | { 9 | bit = 1 << i; // 1左移i位 找到当前操作的位数 10 | // 遍历nums中的所有数 11 | int cnt = 0; 12 | for(auto num : nums) 13 | { 14 | if ((num&bit)!=0) // 如果不为0 ,则cnt++ 这里注意要有括号,位运算的优先级很低 15 | cnt++; 16 | } 17 | 18 | if(cnt%3!=0) // 如果不止3个,说明res在这个位为1 19 | res = res|bit; 20 | } 21 | return res; 22 | } 23 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题57 - II. 和为s的连续正数序列.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | // 使用数学解法,用求和公式+因式分解 6 | // (start+end)(end-start+1) = target*2 7 | vector> findContinuousSequence(int target) { 8 | vector > ans; 9 | target*=2; 10 | for(int i=target/2-1;i>=2;i--)// 因式分解只用遍历到原来的target即可 这里的target是乘了2倍的 去掉i = 1的情况 11 | { 12 | if(target%i==0 && ((i%2)^(target/i%2)))// 如果i整除target 并且 i 和target/i 为不同的奇偶,此时是一个正确的分解 13 | { 14 | int start = (target/i-i+1)/2,end = (target/i+i-1)/2; // 计算start和end 15 | if(start<=0) // 如果start 不满足要求 跳过这种情况 16 | continue; 17 | // 如果满足要求,加入到答案中 18 | vector tmp; 19 | for(int j=start;j<=end;j++) 20 | tmp.push_back(j); 21 | ans.push_back(tmp); 22 | } 23 | } 24 | return ans; 25 | } 26 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题57. 和为s的两个数字.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector twoSum(vector& nums, int target) { 6 | int l = 0; 7 | int r=nums.size()-1; 8 | vector res; 9 | while(ltarget) 19 | r--; 20 | else 21 | l++; 22 | } 23 | return res; 24 | } 25 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题58 - I. 翻转单词顺序.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | string reverseWords(string s) { 6 | if(s.empty())return s; 7 | int len = 0; 8 | string ans = ""; 9 | for(int m = s.size()-1; m >=0; m--) 10 | { 11 | if(s[m]==' '&&len!=0) // 判断是否找到一个单词 12 | { 13 | ans += s.substr(m+1,len)+ " ";len = 0; continue; 14 | } 15 | if(s[m]!= ' ')len++; 16 | } 17 | // 将最后一个单词加入结果,并去掉最后一个空格 18 | if(len !=0) ans += s.substr(0,len) + " "; 19 | if(ans.size()>0)ans.erase(ans.size()-1,1); 20 | return ans; 21 | } 22 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题58 - II. 左旋转字符串.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | // 原地操作版本,将后面的字符往前面移动 6 | string reverseLeftWords(string s, int n) { 7 | if(s.size()==0) return s; 8 | string tmp = s.substr(0,n); 9 | moveString(s,n); 10 | s.replace(s.size()-n,n,tmp); 11 | return s; 12 | } 13 | void moveString(string &s, int n) 14 | { 15 | // 定义函数将字符串s的n位置后的字符向左移动n位 16 | for(int i = n;i<=s.size();i++) 17 | { 18 | s[i-n] = s[i]; 19 | } 20 | } 21 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题59 - II. 队列的最大值.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class MaxQueue { 4 | public: 5 | queue Queue;// 维护数据的队列 6 | deque max_Queue; // 维护最大值的队列 7 | MaxQueue() {} 8 | 9 | int max_value() { 10 | if(Queue.empty()) return -1; 11 | // 获取当前最大值 12 | return max_Queue.front(); 13 | } 14 | 15 | void push_back(int value) { 16 | Queue.push(value); 17 | while(!max_Queue.empty() && value>max_Queue.back()) 18 | max_Queue.pop_back(); 19 | max_Queue.push_back(value); 20 | } 21 | 22 | int pop_front() { 23 | if(Queue.empty()) return -1; 24 | int tmp = Queue.front(); 25 | Queue.pop(); 26 | if(tmp == max_Queue.front()) 27 | max_Queue.pop_front(); 28 | return tmp; 29 | } 30 | }; 31 | 32 | /** 33 | * Your MaxQueue object will be instantiated and called as such: 34 | * MaxQueue* obj = new MaxQueue(); 35 | * int param_1 = obj->max_value(); 36 | * obj->push_back(value); 37 | * int param_3 = obj->pop_front(); 38 | */ -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题60. n个骰子的点数.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | // 使用动态规划的方法实现,定义一个二维的备忘录,横坐标是几个骰子,纵坐标是和为多少 6 | vector twoSum(int n) { 7 | vector res; 8 | if(n==0) return res; 9 | 10 | // 和的取之范围为1-6n 11 | vector > dp(n, vector(6*n,0)); 12 | // 初始化备忘录,将n=1的情况下的1-6定义为1 13 | for(int i=0;i<6;i++) 14 | dp[0][i]=1; 15 | 16 | //从n=2开始计算到n的情况 17 | for(int count = 2;count<=n;count++) 18 | { 19 | for(int sum=count;sum<=6*count;sum++) // 从n遍历到6n 20 | { 21 | for(int i =1;i<=6;i++) 22 | { 23 | if(sum-i<1) // 如果数组越界 结束循环 24 | break; 25 | dp[count-1][sum-1] += dp[count-2][sum-i-1]; 26 | } 27 | } 28 | } 29 | int total = pow(6,n); 30 | for(int i = n;i<=6*n;i++) 31 | { 32 | res.push_back(double(dp[n-1][i-1])/total); 33 | } 34 | return res; 35 | } 36 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题61. 扑克牌中的顺子.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool isStraight(vector& nums) { 6 | int conbo = 0; // 定义连续牌数量 7 | int array[14]={0};// 定义一个数组 第0位统计king的数量 8 | // 遍历统计 9 | for(auto i :nums) 10 | { 11 | if(i==0) // 如果是王 12 | array[0]++; 13 | else 14 | array[i] = 1; 15 | } 16 | // 遍历array判断是否连续5个牌 17 | int flag = 0; // 标记是否开始顺子 18 | for(int i =1;i<=13;i++) 19 | { 20 | if(!flag) 21 | { 22 | if(array[i]!=0)// 如果有这个牌,开始conbo 23 | { 24 | conbo++; 25 | flag++; 26 | } 27 | continue; 28 | } 29 | 30 | // 如果flag为1 31 | if(array[i]!=0) 32 | conbo++; 33 | else if(array[i]==0) //如果没这个牌,就要拿王补 34 | { 35 | if(array[0]>0) 36 | { 37 | array[0]--; 38 | conbo++; 39 | continue; 40 | } 41 | else 42 | break; // 如果没有王补了,就结束 统计conbo数量 43 | } 44 | } 45 | if(conbo+array[0]>=5) 46 | return true; 47 | else 48 | return false; 49 | } 50 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题62. 圆圈中最后剩下的数字.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | // 约瑟夫环,使用数学推倒的方法求解 https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/ 6 | int lastRemaining(int n, int m) { 7 | int a = 0; 8 | for(int i=2;i<=n;i++) // 用迭代备忘录的方法计算 f(2,m) 到f(n,m)的值 9 | { 10 | a = (a+m)%i; // mod i 是因为此时只有i个人 11 | } 12 | return a; 13 | } 14 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题63. 股票的最大利润.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int maxProfit(vector& prices) { 6 | int days = prices.size(); 7 | if(days<=1) return 0; 8 | 9 | vector dp(days,0); 10 | for(int i=days-2;i>=0;i--) 11 | dp[i] = max(dp[i+1],prices[i+1]); 12 | int res=0; 13 | for(int i=0;i constructArr(vector& a) { 6 | vector res; 7 | if(a.size()==0) return res; 8 | // 因为不允许使用除法,所以构建两个备忘录数组记录乘积 9 | vector times1(a.size()+1,1); 10 | vector times2(a.size()+1,1); 11 | // 构建从左到右的乘积数组 12 | for(int i =1;i=0;i--) 18 | { 19 | times2[i] = times2[i+1]*a[i]; 20 | } 21 | // 综合两个数组得出结果 22 | for(int i = 1;i INT_MAX / 10 || (res == INT_MAX / 10 && r > INT_MAX%10)) { 19 | return flag > 0 ? INT_MAX : INT_MIN; 20 | } 21 | // ------------------------------------ 22 | res = res * 10 + r; 23 | i++; 24 | } 25 | return flag > 0 ? res : -res; 26 | } 27 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题68 - I. 二叉搜索树的最近公共祖先.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 13 | if(root == NULL) return NULL; 14 | int m = min(p->val,q->val); 15 | int n = max(p->val,q->val); // 获取两个节点的值 标记为最大和最小方便比较 16 | TreeNode* cur = root; 17 | while(cur!=NULL) 18 | { 19 | if(cur->val >m && cur->valval == m || cur->val == n) // 如果有一个目标就是当前节点,说明他就是公共祖先 22 | break; 23 | if(cur->valright; 25 | else if(cur->val>n) 26 | cur = cur->left; 27 | } 28 | return cur; 29 | } 30 | }; -------------------------------------------------------------------------------- /Leetcode 剑指offer 面试题库/面试题68 - II. 二叉树的最近公共祖先.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | TreeNode * res; 6 | Solution():res(NULL){} 7 | 8 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 9 | // 深度优先搜索搜索 10 | helper(root,p,q); 11 | return res; 12 | } 13 | bool helper(TreeNode* root, TreeNode* p, TreeNode* q) { 14 | if(root == NULL) return false; 15 | if(root == p || root == q) 16 | { 17 | if(helper(root->left,p,q) || helper(root->right,p,q)) 18 | res = root; 19 | return true; 20 | } 21 | bool left = helper(root->left,p,q); 22 | bool right = helper(root->right,p,q); 23 | if(left && right) 24 | { 25 | res = root; 26 | return true; 27 | } 28 | else if(left || right) 29 | return true; 30 | return false; 31 | } 32 | }; -------------------------------------------------------------------------------- /Leetcode 程序员面试金典/面试题 01.06. 字符串压缩.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | string compressString(string S) { 6 | if(S.size()==0) return S; 7 | int count = 0; 8 | char cur; 9 | string res; 10 | for(int i =0;inext; 16 | 17 | // 如果链表有k个节点,双指针同时向后遍历 18 | ListNode* pre = head; 19 | while(front->next!=NULL) 20 | { 21 | front = front->next; 22 | pre = pre->next; 23 | } 24 | return pre->val; 25 | } 26 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/10. 正则表达式匹配【递归】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool isMatch(string s, string p) 6 | { 7 | //二者有一个长度为0 8 | if(s.size()==0) 9 | { 10 | // cout<<"hi"; 11 | // system("pause"); 12 | if(p.size()%2==0) 13 | { 14 | for(int i=1;i=0&&p[lenp-1]=='*') lenp--; 39 | if(p[lenp-1]!='.'&&p[lenp-1]!=s[lens])//末尾两位都不匹配 40 | { 41 | // cout<<"s:"<> levelOrder(TreeNode* root) { 13 | vector > res; 14 | if(root == NULL) return res; 15 | queue myqu; 16 | vector subres; // 保存每一层的答案 17 | myqu.push(root); 18 | subres.push_back(root->val); 19 | while(!myqu.empty()) 20 | { 21 | int s = subres.size(); // 获取每一层有多少个元素 22 | res.push_back(subres); 23 | vector().swap(subres);// 清空 24 | for(int i =0;ileft != NULL) 28 | { 29 | myqu.push(cur->left); 30 | subres.push_back(cur->left->val); 31 | } 32 | 33 | if(cur->right != NULL) 34 | { 35 | myqu.push(cur->right); 36 | subres.push_back(cur->right->val); 37 | } 38 | myqu.pop(); 39 | } 40 | } 41 | return res; 42 | } 43 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/126.单词接龙【图】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int ladderLength(string beginWord, string endWord, vector& wordList) { 6 | queue q; 7 | map m1; //储存容器中的字符串便于查找是否存在 8 | map re; //储存路径长度的结果,beginword为1 9 | int n = wordList.size(); 10 | for(int i = 0; i < n; i ++) 11 | m1[wordList[i]] = 1; 12 | re[beginWord] = 1; 13 | q.push(beginWord); 14 | while ((!q.empty()) && m1.size()) 15 | { 16 | string now = q.front(); 17 | q.pop(); 18 | int num = re[now]; 19 | int llen = now.size(); 20 | for (int i = 0; i < llen; i ++) 21 | { 22 | string temp = now; 23 | for(char c = 'a' ; c <= 'z'; c ++)//当单词表很大的时候,遍历26个字母可能比遍历列表要快 24 | { 25 | if(temp[i] == c) 26 | continue; 27 | else 28 | temp[i] = c; 29 | if(m1.find(temp) != m1.end()) 30 | { 31 | if(temp == endWord) 32 | return num + 1; 33 | q.push(temp); 34 | re[temp] = num + 1; 35 | m1.erase(temp);//删除这个单词防止又回到这个单词上遍历 36 | } 37 | } 38 | } 39 | } 40 | return 0; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /My-Leetcode/Cpp/133. 克隆图【图】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Node { 4 | public: 5 | int val; 6 | vector neighbors; 7 | 8 | Node() {} 9 | 10 | Node(int _val, vector _neighbors) { 11 | val = _val; 12 | neighbors = _neighbors; 13 | } 14 | }; 15 | class Solution { 16 | public: 17 | Node* connectNode(Node *last,Node* node,vector &f) 18 | { 19 | vector::iterator result = f.begin(); 20 | for(;result!=f.end();result++) 21 | { 22 | if((*result)->val==node->val) 23 | { 24 | break; 25 | } 26 | } 27 | if(result!=f.end()) 28 | { 29 | last->neighbors.push_back((*result));//相互之间连边 30 | return NULL; 31 | } 32 | //如果节点不存在 则建立节点 33 | Node *temp = new Node; 34 | f.push_back(temp); 35 | temp->val=node->val; 36 | last->neighbors.push_back(temp);//相互之间连边 37 | return temp; 38 | } 39 | void recursion(Node *new_graph,Node*ori_graph,vector &f) 40 | { 41 | Node *temp; 42 | for(int i=0;i < ori_graph->neighbors.size();i++) 43 | { 44 | if(temp = connectNode(new_graph,ori_graph->neighbors[i],f)) 45 | { 46 | recursion(temp,ori_graph->neighbors[i],f); 47 | } 48 | } 49 | } 50 | Node* cloneGraph(Node* node) 51 | { 52 | if(node == NULL) return NULL; 53 | vector f;//已经建立的节点 54 | Node *new_graph = new Node; // 新的图的第一个节点 55 | 56 | f.push_back(new_graph); 57 | new_graph->val = node->val; 58 | recursion(new_graph,node,f); 59 | return new_graph; 60 | } 61 | }; 62 | int main() 63 | { 64 | //https://github.com/ysyisyourbrother/Leetcode.git 65 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/134. 加油站【贪心算法】.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 这道转圈加油问题不算很难,只要想通其中的原理就很简单。我们首先要知道能走完整个环的前提是gas的总量 3 | 要大于cost的总量,这样才会有起点的存在。假设开始设置起点start = 0, 并从这里出发,如果当前的gas值大于 4 | cost值,就可以继续前进,此时到下一个站点,剩余的gas加上当前的gas再减去cost,看是否大于0,若大于0, 5 | 则继续前进。当到达某一站点时,若这个值小于0了,则说明从起点到这个点中间的任何一个点都不能作为起 6 | 点,则把起点设为下一个点,继续遍历。当遍历完整个环时,当前保存的起点即为所求。代码如下: 7 | */ 8 | class Solution { 9 | public: 10 | int canCompleteCircuit(vector& gas, vector& cost) { 11 | int total = 0, sum = 0, start = 0; 12 | for (int i = 0; i < gas.size(); ++i) { 13 | total += gas[i] - cost[i]; 14 | sum += gas[i] - cost[i]; 15 | if (sum < 0) { 16 | start = i + 1; 17 | sum = 0; 18 | } 19 | } 20 | return (total < 0) ? -1 : start; 21 | } 22 | }; 23 | int main() 24 | { 25 | 26 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/135. 分发糖果【贪心算法】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | /* 4 | 假设严格递增的序列是增序列,非严格递增(递减或者相等)的序列是减序列,则题目给定的序列必定又增减序列交替组成的 5 | 从左往右数组,对每个增子序列,都从1开始递增,但此时对减子序列就无效,因为有可能是这样的序列1 2 3 2 1 0, 6 | 但每个小朋友又必须至少1个糖果最后一个小朋友不符合,则糖果数量就要改成 1 2 4 3 2 1 可知从左往右只能确定递增序列的结果。 7 | 因此我们同理从右边向左边再遍历一次,这样可以确定递减序列,让每一个递减子序列从最后一个元素从1开始反向递增。 8 | 最后我们把两个列表和并,取最大的值即可。 9 | */ 10 | class Solution { 11 | public: 12 | int candy(vector& ratings) { 13 | int n=ratings.size(),sum=0; 14 | vector left(n,1),right(n,1); // 定义数组都初始化为1 15 | for(int i=1;iratings[i-1]) 17 | left[i]=left[i-1]+1; 18 | } 19 | for(int i=n-2;i>=0;i--){ 20 | if(ratings[i]>ratings[i+1]) 21 | right[i]=right[i+1]+1; 22 | sum+=max(left[i],right[i]); 23 | } 24 | sum+=max(right[n-1],left[n-1]); 25 | return sum; 26 | } 27 | }; 28 | int main() 29 | { 30 | 31 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/136. 只出现一次的数字1【位运算】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int singleNumber(vector& nums) { 6 | // 任何数字和本身异或是0,和0异或是本身,因此直接异或就可以做出 7 | int res = 0; 8 | for(auto i : nums) 9 | res^i; 10 | return res; 11 | } 12 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/144. 二叉树的前序遍历【递归 迭代】.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // 引入标准模板库stack头文件 3 | using namespace std; 4 | 5 | struct Tree 6 | { 7 | char data; 8 | Tree* Lson; 9 | Tree* Rson; 10 | }; 11 | 12 | // 非递归前序遍历 13 | void PreOrder_Nor1(Tree* tree) 14 | { 15 | 16 | if (tree == NULL) 17 | return; 18 | stacks; //创建一个空栈 19 | while (tree != NULL || !s.empty()) 20 | { 21 | while (tree != NULL) 22 | { 23 | cout << tree->data << " "; 24 | s.push(tree); 25 | tree = tree->Lson; 26 | } 27 | if (!s.empty()) 28 | { 29 | tree = s.top(); 30 | tree = tree->Rson; 31 | s.pop(); 32 | } 33 | } 34 | } 35 | 36 | vector preorderTraversal(TreeNode* root) { 37 | stack S; 38 | vector v; 39 | TreeNode* rt = root; 40 | while(rt || S.size()){ 41 | while(rt){ 42 | S.push(rt->right); 43 | v.push_back(rt->val); 44 | rt=rt->left; 45 | } 46 | rt=S.top();S.pop(); 47 | } 48 | return v; 49 | } 50 | -------------------------------------------------------------------------------- /My-Leetcode/Cpp/145. 二叉树的后序遍历【递归 迭代】.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // 引入标准模板库stack头文件 3 | using namespace std; 4 | 5 | struct Tree 6 | { 7 | char data; 8 | Tree* Lson; 9 | Tree* Rson; 10 | }; 11 | 12 | //非递归后序遍历 13 | void PosOrder(Tree* tree) 14 | { 15 | if (tree == NULL) 16 | return; 17 | stacks; //创建一个空栈 18 | Tree* pPre = NULL; 19 | s.push(tree); 20 | while (!s.empty()) 21 | { 22 | tree = s.top(); 23 | if ((tree->Rson == NULL && tree->Rson == NULL) || 24 | (pPre != NULL && (tree->Lson == pPre || tree->Rson == pPre))) 25 | { 26 | cout << tree->data << " "; 27 | pPre = tree; 28 | s.pop(); 29 | } 30 | else 31 | { 32 | if (tree->Rson != NULL) 33 | s.push(tree->Rson); 34 | if (tree->Lson != NULL) 35 | s.push(tree->Lson); 36 | } 37 | } 38 | } 39 | 40 | vector postorderTraversal(TreeNode* root) { 41 | stack S; 42 | vector v; 43 | TreeNode* rt = root; 44 | while(rt || S.size()){ 45 | while(rt){ 46 | S.push(rt->left); 47 | v.push_back(rt->val); 48 | rt=rt->right; 49 | } 50 | rt=S.top();S.pop(); 51 | } 52 | reverse(v.begin(),v.end()); 53 | return v; 54 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/206. 反转链表【链表】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | struct ListNode { 3 | int val; 4 | ListNode *next; 5 | ListNode(int x) : val(x), next(NULL) {} 6 | }; 7 | class Solution { 8 | public: 9 | // 迭代的方法实现反转列表 10 | ListNode* reverseList1(ListNode* head) 11 | { 12 | ListNode* cur = head; 13 | ListNode* res = NULL; 14 | while(cur != NULL) 15 | { 16 | ListNode* tmp = new ListNode(*cur); 17 | tmp->next = res; 18 | res = tmp; 19 | cur = cur->next; 20 | } 21 | return res; 22 | } 23 | 24 | // 使用递归的方法反转链表 25 | ListNode* reverseList(ListNode* head) { 26 | return reverse(NULL,head); 27 | } 28 | ListNode* reverse(ListNode *pre,ListNode *cur){ 29 | if(cur==NULL) return pre; 30 | ListNode* next = cur->next; 31 | cur->next = pre; 32 | return reverse(cur,next); 33 | } 34 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/207. 课程表【广度优先搜索实现拓扑排序】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution{ 4 | public: 5 | bool canFinish(int numCourses, vector>& prerequisites) 6 | { 7 | if(prerequisites.size()==0) 8 | return true; 9 | vector > adj; 10 | for(int i=0;i a; 13 | adj.push_back(a); 14 | } 15 | int indegree[5000]={0}; //定义一个收集每个点入度的列表 16 | for(int i=0;i q; 23 | for(int i=0;ival > tmp2->val)// tmp2比较小,先将tmp2的加入res链表中 19 | { 20 | cur->next = tmp2; 21 | tmp2 = tmp2->next; 22 | cur = cur->next; 23 | } 24 | else 25 | { 26 | cur->next = tmp1; 27 | tmp1 = tmp1->next; 28 | cur = cur->next; 29 | } 30 | } 31 | if(tmp1==NULL) // 如果tmp1为空,就直接将tmp2接在res后面即可 32 | { 33 | cur->next = tmp2; 34 | } 35 | if(tmp2 == NULL) 36 | { 37 | cur->next = tmp1; 38 | } 39 | return res->next; 40 | } 41 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/210. 课程表 II【广度优先搜索+拓扑排序】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution{ 4 | public: 5 | vector findOrder(int numCourses, vector>& prerequisites) 6 | { 7 | vector res; 8 | vector null; 9 | vector > adj; 10 | for(int i=0;i a; 13 | adj.push_back(a); 14 | } 15 | int indegree[5000]={0}; //每个顶点的入度,用数组表示 16 | for(int i=0;i q; 24 | for(int i=0;i 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void MinHeap(vector &v,int i,int height) 7 | { 8 | int left=2*i+1; 9 | int right=2*i+2; 10 | int smallest=i; 11 | if(v[left]v[right]&&right<=height) 16 | { 17 | smallest=right; 18 | } 19 | if(smallest!=i) 20 | { 21 | swap(v[smallest],v[i]); 22 | MinHeap(v,smallest,height); 23 | } 24 | } 25 | void buildMinHeap(vector &v) 26 | { 27 | for(int i=(v.size()-1)/2;i>=0;i--) 28 | { 29 | MinHeap(v, i,v.size()-1); 30 | } 31 | } 32 | int select_kth_smallest(vector v, size_t k) 33 | { 34 | buildMinHeap(v); 35 | int height=v.size()-1; 36 | while(k--) 37 | { 38 | swap(v[0],v[height]); 39 | height--; 40 | MinHeap(v,0,height); 41 | } 42 | return v[height+1]; 43 | } 44 | int main() 45 | { 46 | vector vec; 47 | for(int i=17;i>=4;i--) 48 | { 49 | vec.push_back(i); 50 | } 51 | cout<val); 18 | res->left = invertTree(root->right); 19 | res->right = invertTree(root->left); 20 | return res; 21 | } 22 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/230. 二叉搜索树中第K小的元素【二叉树】.cpp: -------------------------------------------------------------------------------- 1 | # include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | 10 | class Solution { 11 | public: 12 | int recursion(TreeNode* root, int& k) 13 | { 14 | if(root == NULL) 15 | { 16 | return 0; 17 | } 18 | int res = recursion(root->left,k); //因为是二叉搜索树,用前序遍历的方法实现 19 | if(k==0) 20 | { 21 | return res; 22 | } 23 | k-=1; // 遍历当前根节点 24 | if(k==0) 25 | { 26 | return root->val; 27 | } 28 | res = recursion(root->right,k); 29 | if(k==0) 30 | { 31 | return res; 32 | } 33 | return 0; 34 | } 35 | int kthSmallest(TreeNode* root, int k) { 36 | return recursion(root, k); 37 | } 38 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/240. 搜索二维矩阵 II【二分查找法】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | /* 4 | 二分查找法,从左下角或者右上角开始查找,根据大小决定行数向上(下)移动或者列数向右(左)移动 5 | */ 6 | class Solution { 7 | public: 8 | bool searchMatrix(vector>& matrix, int target) { 9 | if (matrix.empty() || matrix[0].empty()) return false; 10 | int x = matrix.size() - 1, y = 0; 11 | while (true) { 12 | if (matrix[x][y] > target) --x; 13 | else if (matrix[x][y] < target) ++y; 14 | else return true; 15 | if (x < 0 || y >= matrix[0].size()) break; 16 | } 17 | return false; 18 | } 19 | }; 20 | int main() 21 | { 22 | 23 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/263. 丑数【数学】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool isUgly(int num) { 6 | if(num==0) return false; 7 | while(num%2==0) 8 | num/=2; 9 | while(num%3==0) 10 | num/=3; 11 | while(num%5==0) 12 | num/=5; 13 | if(num==1) 14 | return true; 15 | return false; 16 | } 17 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/264. 丑数 II【三指针】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int nthUglyNumber(int n) { 6 | if(n==0) return 0; 7 | vector res; // 动态规划的方法 三指针 8 | res.push_back(1);// 1 为丑数 9 | int p=0,q=0,r=0; 10 | while(res.size()>& board) 6 | { 7 | bool grid[9][9];//定义9个方格 8 | bool col[9][9];//定义9列 9 | bool row[9][9];//定义9行 10 | for(int i=0;i<9;i++) 11 | { 12 | for(int j=0;j<9;j++) 13 | { 14 | grid[i][j]=0; 15 | col[i][j]=0; 16 | row[i][j]=0; 17 | } 18 | } 19 | for(int i=0;i<9;i++) 20 | { 21 | for(int j=0;j<9;j++) 22 | { 23 | int tem; 24 | if (board[i][j]=='.') 25 | continue; 26 | else 27 | tem=board[i][j]-'0'-1; 28 | int g=i/3+(j/3)*3; 29 | if(grid[g][tem]==0 && col[i][tem]==0 && row[j][tem]==0)//这里可以放置这个数字 30 | { 31 | grid[g][tem]=1; 32 | col[i][tem]=1; 33 | row[j][tem]=1; 34 | } 35 | else 36 | { 37 | return false; 38 | } 39 | } 40 | } 41 | return true; 42 | } 43 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/39. 组合总和【递归】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | void recursion(int i,vector > &Result,vector res,vector& candidates,int target) 4 | { 5 | int tar=target; 6 | for(;i=candidates[i]) 9 | { 10 | res.push_back(candidates[i]); 11 | recursion(i,Result,res,candidates,tar-candidates[i]); 12 | res.pop_back(); 13 | } 14 | } 15 | if(target==0) 16 | { 17 | Result.push_back(res); 18 | } 19 | } 20 | vector > combinationSum(vector& candidates, int target) 21 | { 22 | vector > result; 23 | if(candidates.size()==0) 24 | { 25 | return result; 26 | } 27 | vector res; 28 | recursion(0,result,res,candidates,target); 29 | 30 | return result; 31 | } 32 | 33 | int main() 34 | { 35 | vector a; 36 | a.push_back(2); 37 | a.push_back(3); 38 | a.push_back(6); 39 | a.push_back(7); 40 | vector > res = combinationSum(a,7); 41 | for(int i=0;i > &Result,vector res,vector& candidates,int target) 4 | { 5 | int tar=target; 6 | for(int i = start;istart&&candidates[i]==candidates[i-1]) continue;//关键步骤 9 | if(tar>=candidates[i]) 10 | { 11 | 12 | res.push_back(candidates[i]); 13 | recursion(i+1,Result,res,candidates,tar-candidates[i]); 14 | res.pop_back(); 15 | } 16 | } 17 | if(target==0) 18 | { 19 | Result.push_back(res); 20 | } 21 | } 22 | vector > combinationSum2(vector& candidates, int target) 23 | { 24 | vector > result; 25 | if(candidates.size()==0) 26 | { 27 | return result; 28 | } 29 | sort(candidates.begin(),candidates.end()); 30 | vector res; 31 | recursion(0,result,res,candidates,target); 32 | unique(result.begin(),result.end()); 33 | 34 | return result; 35 | } 36 | 37 | int main() 38 | { 39 | vector a; 40 | a.push_back(10); 41 | a.push_back(1); 42 | a.push_back(2); 43 | a.push_back(7);a.push_back(6);a.push_back(1);a.push_back(5); 44 | vector > res = combinationSum2(a,8); 45 | for(int i=0;i& nums) 6 | { 7 | int res; 8 | int time[100000]; 9 | for(int i=0;icur_far) 18 | { 19 | if(index+nums[index]>=nums.size()-1) return time[index]+1; 20 | int i =cur_far+1; 21 | cur_far=index+nums[index]; 22 | for(;i<=cur_far;i++) 23 | { 24 | time[i]=time[index]+1; 25 | } 26 | } 27 | } 28 | return time[nums.size()-1]; 29 | } 30 | }; 31 | int main() 32 | { 33 | Solution test; 34 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/455. 分发饼干【贪心算法】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int findContentChildren(vector& g, vector& s) { 6 | sort(g.begin(),g.end()); 7 | sort(s.begin(),s.end()); 8 | int i=0,j=0; 9 | int res=0; 10 | if(g.size()==0||s.size()==0) return 0; 11 | while(j=g[i]) 14 | { 15 | res++; 16 | j++,i++; 17 | } 18 | else 19 | { 20 | j++; 21 | } 22 | } 23 | return res; 24 | } 25 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/46. 全排列【递归】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | /* 4 | ######求解全排列的方法####### 5 | 6 | ###交换法### 7 | 1、首先看最后两个数4, 5。 它们的全排列为4 5和5 4, 即以4开头的5的全排列和以5开头的4的全排列。 8 | 由于一个数的全排列就是其本身,从而得到以上结果。 9 | 2、再看后三个数3, 4, 5。它们的全排列为3 4 5、3 5 4、 4 3 5、 4 5 3、 5 3 4、 5 4 3 六组数。 10 | 即以3开头的和4,5的全排列的组合、以4开头的和3,5的全排列的组合和以5开头的和3,4的全排列的组合. 11 | 于是根据上面的说法,就可以明白为什么可以用交换实现! 12 | 13 | */ 14 | class Solution { 15 | public: 16 | void recursion(vector >&res,vector& nums,int cur=0) 17 | { 18 | if(cur==nums.size()-1)//递归到nums的最后一个数字的时候,直接加入res结果并返回 19 | { 20 | res.push_back(nums); 21 | return; 22 | } 23 | for(int i=cur;i> permute(vector& nums) 37 | { 38 | vector > res; 39 | if(nums.size()==0) return res; 40 | recursion(res,nums); 41 | return res; 42 | } 43 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/47. 全排列 II【递归】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | /* 4 | 求解方法和全排列几乎一样,就加了一个用map去重复的方法。 5 | */ 6 | class Solution { 7 | public: 8 | void recursion(vector >&res,vector& nums,int cur=0) 9 | { 10 | if(cur==nums.size()-1)//递归到nums的最后一个数字的时候,直接加入res结果并返回 11 | { 12 | res.push_back(nums); 13 | return; 14 | } 15 | map mymap;//定义一个map来帮忙去重 16 | for(int i=cur;i> permuteUnique(vector& nums) 34 | { 35 | vector > res; 36 | if(nums.size()==0) return res; 37 | recursion(res,nums); 38 | return res; 39 | } 40 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/53. 最大子序和【动态规划 分治法】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | //动态规划 时间复杂度o(n) 6 | int maxSubArray(vector& nums) { 7 | if(nums.size()==0) return 0; 8 | int a[1000]; 9 | int Max = a[0]=nums[0]; 10 | for(int i=1;i0) a[i]=a[i-1]+nums[i]; 13 | else a[i]=nums[i]; 14 | if(a[i]>Max) Max=a[i]; 15 | } 16 | return Max; 17 | } 18 | //分治法 时间复杂度o(nlogn) 19 | /*思路:将数组分为左右两部分,用递归求解方法分别求最大子序和,再将左右两部分和中间值nums[mid]进行整合,先将nums[mid]和左边部分进行整合,再和右边进行整合,用两个for循环;最终得到左半边最大子序和l,右半边最大子序和r,和num_max,这三个的最大值就是最后的答案。*/ 20 | int maxSubArray2(vector& nums) { 21 | if(nums.size()==0) return NULL; 22 | return fenzhifa(nums,0,nums.size()-1); 23 | } 24 | int fenzhifa(vector& nums,int left,int right) 25 | { 26 | if(left>right) return INT_MIN; 27 | if(left==right) return nums[left]; 28 | int mid=(left+right)/2; 29 | int l=fenzhifa(nums,0,mid-1);//求左半边最大子序和 30 | int r=fenzhifa(nums,mid+1,right);//求右半边最大子序和 31 | 32 | int t=nums[mid]; 33 | int max_num=nums[mid]; 34 | 35 | for(int i=mid-1;i>=left;i--)//整合左半部分 36 | { 37 | t+=nums[i]; 38 | max_num=max(max_num,t); 39 | } 40 | t=max_num; 41 | for(int i=mid+1;i<=right;i++)//整合右半部分 42 | { 43 | t+=nums[i]; 44 | max_num=max(max_num,t); 45 | } 46 | return max(max(r,l),max_num); 47 | } 48 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/54. 螺旋矩阵【数组】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | vector spiralOrder(vector>& matrix) { 6 | vector res; 7 | if(matrix.size()==0||matrix[0].size()==0) return res; 8 | vector > judge(matrix.size(),vector(matrix[0].size(),0)); // 定义一个判断的矩阵。 9 | 10 | int x= 0,y=0;// 定义起始位置 11 | res.push_back(matrix[x][y]); 12 | judge[0][0] =1; 13 | int flag = 1; 14 | while(flag) 15 | { 16 | flag = 0; //如果都没得走,结束循环 17 | // 先向右走 18 | while(is_legal(x,y+1,judge)) 19 | y++,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 20 | 21 | // 向下走 22 | while(is_legal(x+1,y,judge)) 23 | x++,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 24 | 25 | //向左走 26 | while(is_legal(x,y-1,judge)) 27 | y--,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 28 | 29 | while(is_legal(x-1,y,judge)) 30 | x--,res.push_back(matrix[x][y]),flag=1,judge[x][y]=1; 31 | } 32 | return res; 33 | } 34 | bool is_legal(int x,int y, vector >& judge) 35 | { 36 | int limit_x = judge.size(); 37 | int limit_y = judge[0].size(); 38 | if(x>=0 && x=0 && y& nums) 7 | { 8 | if(nums.size()==0) return true; 9 | int cur_far=0; //目前能到达最远的位置 10 | int index=0;//目前探测到的位置 11 | for(;index<=cur_far&&cur_farcur_far) 14 | cur_far=index+nums[index]; 15 | } 16 | if(cur_far>=nums.size()-1) 17 | { 18 | return true; 19 | } 20 | return false; 21 | } 22 | }; 23 | int main() 24 | { 25 | Solution test; 26 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/62. 不同路径【动态规划】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | /*动态规划来求解,们可以维护一个二维数组dp,其中dp[i][j]表示到当前位置不同的走法的个数, 6 | 然后可以得到递推式为: dp[i][j] = dp[i - 1][j] + dp[i][j - 1], 7 | 这里为了节省空间,我们使用一维数组dp,一行一行的刷新也可以*/ 8 | int uniquePaths(int m, int n) { 9 | vector dp(n, 1); 10 | for (int i = 1; i < m; ++i) { 11 | for (int j = 1; j < n; ++j) { 12 | dp[j] += dp[j - 1]; 13 | } 14 | } 15 | return dp[n - 1]; 16 | } 17 | /*排列组合求解:实际相当于机器人总共走了m + n - 2步,其中m - 1步向右走,n - 1步向下走 18 | 那么总共不同的方法个数就相当于在步数里面m - 1和n - 1中较小的那个数的取法,实际上是一道组合数的问题*/ 19 | int uniquePaths2s(int m, int n) { 20 | double num = 1, denom = 1; 21 | int small = m > n ? n : m; 22 | for (int i = 1; i <= small - 1; ++i) { 23 | num *= m + n - 1 - i; 24 | denom *= i; 25 | } 26 | return (int)(num / denom); 27 | } 28 | }; 29 | int main() 30 | { 31 | 32 | } -------------------------------------------------------------------------------- /My-Leetcode/Cpp/63. 不同路径II【动态规划】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int uniquePathsWithObstacles(vector>& obstacleGrid) { 6 | int hei=obstacleGrid.size(); 7 | int wid=obstacleGrid[0].size(); 8 | if(hei==0||wid==0) return 0;//图是空的 9 | 10 | long long matrix[150][150]; 11 | if (obstacleGrid[0][0]==0)//第一个点就无路可走 12 | { 13 | matrix[0][0]=1; 14 | } 15 | else return 0; 16 | for(int i=1;i>& grid) { 6 | if(grid.size()==0) return 0; 7 | vector dp(grid[0]);// 只需要一个数组的dp 初始化为grid的第一行 8 | for(int i=1;i& nums) { 6 | if(nums.size()==0) return 0; 7 | int dp[10005];// 动态规划,也可以不用开数组直接用一个count记录dp[i-1]的值 8 | dp[0]=1; 9 | int res=1; 10 | for(int i=1;inums[i-1]) 13 | dp[i]=dp[i-1]+1; 14 | else 15 | { 16 | res=res>dp[i-1]?res:dp[i-1]; 17 | dp[i]=1; 18 | } 19 | } 20 | res=res>dp[nums.size()-1]?res:dp[nums.size()-1]; 21 | return res; 22 | } 23 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/704. 二分查找【二分查找法】.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int search(vector& nums, int target) { 4 | int l = 0; 5 | int r = nums.size()-1; 6 | while(l& words, string S) { 6 | string res; 7 | if(S.size()==0) return res; 8 | vector judge(S.size(),0); 9 | for(auto word : words) 10 | { 11 | int index = 0; 12 | while(index 32 | res+=""; 33 | res += S[i]; 34 | } 35 | else//如果为1,判断前一位 36 | { 37 | if(i==0 || judge[i-1]==0) //如果前一位为0,则加粗 38 | res+=""; 39 | res+=S[i]; 40 | } 41 | } 42 | // 单独考虑最后一个字符 43 | if(judge[S.size()-1]==1) 44 | res+=""; 45 | return res; 46 | } 47 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/785. 判断二分图【深度优先搜索+图】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | bool dfs(vector>& graph,int i,int *find,int last){ 6 | find[i]=-last; // 给它分配为和上一个点不一样的类 7 | // for(int a=0;a>& graph) { 31 | int *find=new int[graph.size()];// 声明一个和点的个数相同的数组 0--未遍历 1--第一类 -1--第二类 32 | memset(find,0,sizeof(int)*graph.size());//全部初始化为0 33 | for(int i=0;i>& flights, int src, int dst, int k) { 11 | vectorcost(n,1e6);cost[src]=0;///将所有权值设为inf,考虑到取值范围为[1, 10000].设为1e6即可。 12 | for(int i=0;i<=k;i++){ 13 | vectorc(cost);//控制每次大循环最多只会增加一次转机次数 14 | for(auto&e:flights) 15 | c[e[1]]=min(c[e[1]],cost[e[0]]+e[2]);//松弛 16 | cost=c; 17 | } 18 | return cost[dst]==1e6?-1:cost[dst]; 19 | } 20 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/87. 扰乱字符串【递归】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | // Recursion 4 | /* 5 | s1和s2是scramble的话,那么必然存在一个在s1上的长度l1,将s1分成s11和s12两段,同样有s21和s22.那么要么s11和s21是scramble的并且s12和s22是scramble的;要么s11和s22是scramble的并且s12和s21是scramble的。就拿题目中的例子 rgeat 和 great 来说,rgeat 可分成 rg 和 eat 两段, great 可分成 gr 和 eat 两段,rg 和 gr 是scrambled的, eat 和 eat 当然是scrambled。根据这点,我们可以写出代码如下 6 | */ 7 | class Solution { 8 | public: 9 | bool isScramble(string s1, string s2) { 10 | if (s1.size() != s2.size()) return false; 11 | if (s1 == s2) return true; 12 | string str1 = s1, str2 = s2; 13 | sort(str1.begin(), str1.end()); 14 | sort(str2.begin(), str2.end()); 15 | if (str1 != str2) return false; 16 | for (int i = 1; i < s1.size(); ++i) { 17 | string s11 = s1.substr(0, i); 18 | string s12 = s1.substr(i); 19 | string s21 = s2.substr(0, i); 20 | string s22 = s2.substr(i); 21 | if (isScramble(s11, s21) && isScramble(s12, s22)) return true; 22 | s21 = s2.substr(s1.size() - i); 23 | s22 = s2.substr(0, s1.size() - i); 24 | if (isScramble(s11, s21) && isScramble(s12, s22)) return true; 25 | } 26 | return false; 27 | } 28 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/88. 合并两个有序数组.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | void merge(vector& nums1, int m, vector& nums2, int n) { 6 | // 定义两个指针,同时向右边移动遍历数组 7 | int l1 = 0; 8 | int l2 = 0; 9 | int cur_size = m; // 记录nums1当前有效数字的长度 10 | while(l1=cur_size) 24 | { 25 | // 如果l1到达了m的位置,把nums2剩下的数字补上去 26 | while(l1& nums1, int begin, int end) 36 | { 37 | // 将nums1数据元素 从begin位置开始到end位置的数字向右移动一位 38 | for(int i = end;i>=begin;i--) 39 | { 40 | nums1[i+1] = nums1[i]; 41 | } 42 | } 43 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/91. 解码方法【动态规划】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | // 简单动态规划 dp[i] = dp[i-1]+dp[i - 2]; 4 | class Solution { 5 | public: 6 | int numDecodings(string s) { 7 | if (s.empty() || (s.size() > 1 && s[0] == '0')) return 0; // 如果是空的或者第一个就是0 8 | vector dp(s.size()+1, 0);//dp[i] 中的i表示到第几个字符的可能组合数 定义空串的组合数是1,这样就不用再单独讨论i=2的情况了 9 | dp[0] = 1,dp[1]=1; 10 | for (int i = 1; i < s.size()+1; ++i) { 11 | dp[i] = (s[i - 1] == '0') ? 0 : dp[i - 1]; 12 | if (i > 1 && (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6'))) { 13 | dp[i] += dp[i - 2]; 14 | } 15 | } 16 | return dp.back(); 17 | } 18 | }; -------------------------------------------------------------------------------- /My-Leetcode/Cpp/94. 二叉树的中序遍历【递归 迭代】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | vector inorderTraversal(TreeNode* root) { 4 | stack S; 5 | vector v; 6 | TreeNode* rt = root; 7 | while(rt || S.size()){ 8 | while(rt){ 9 | S.push(rt); 10 | rt=rt->left; 11 | } 12 | rt=S.top();S.pop(); 13 | v.push_back(rt->val); 14 | rt=rt->right; 15 | } 16 | return v; 17 | } 18 | -------------------------------------------------------------------------------- /My-Leetcode/Cpp/95. 不同的二叉搜索树 II【递归+深度优先搜索+动态规划】.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct TreeNode { 4 | int val; 5 | TreeNode *left; 6 | TreeNode *right; 7 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | }; 9 | class Solution { 10 | public: 11 | vector generateTrees(int n) { 12 | if (n == 0) 13 | return vector{}; 14 | return recursion(1,n); 15 | } 16 | vector recursion(int begin, int end) // 递归函数,递归建造从start到end的所有可能二叉树并用vector收集起来 17 | { 18 | vector res;// 返回start 到end每个树的根指针 19 | if (begin > end)// 结束递归条件 20 | { 21 | res.push_back(NULL); 22 | return res; 23 | } 24 | for (int i = begin; i <= end; ++i) 25 | { 26 | vector left_trees = recursion(begin, i-1);//递归建立左边的树 27 | vector right_trees = recursion(i+1, end);//递归右边的树 28 | for (auto l : left_trees) 29 | { 30 | for (auto r : right_trees) 31 | { 32 | //重复用了建造好的树指针,也可以算是一个动态规划 33 | TreeNode* root = new TreeNode(i); 34 | root->left = l; 35 | root->right = r; 36 | res.push_back(root); 37 | } 38 | } 39 | 40 | } 41 | return res; 42 | } 43 | }; -------------------------------------------------------------------------------- /My-Leetcode/Go/1.两数之和【哈希】.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1 lang=golang 3 | * 4 | * [1] 两数之和 5 | */ 6 | 7 | // @lc code=start 8 | func twoSum(nums []int, target int) []int { 9 | hashTable := map[int]int{} 10 | for i, x := range nums { 11 | if p, ok := hashTable[target-x]; ok { 12 | return []int{p, i} 13 | } 14 | hashTable[x] = i 15 | } 16 | return nil 17 | } 18 | 19 | // @lc code=end 20 | 21 | -------------------------------------------------------------------------------- /My-Leetcode/Go/10.正则表达式匹配.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=10 lang=golang 3 | * 4 | * [10] 正则表达式匹配 5 | */ 6 | 7 | // @lc code=start 8 | func isMatch(s string, p string) bool { 9 | m, n := len(s), len(p) 10 | matches := func(i, j int) bool { 11 | if i == 0 { 12 | return false 13 | } 14 | if p[j-1] == '.' { 15 | return true 16 | } 17 | return s[i-1] == p[j-1] 18 | } 19 | 20 | f := make([][]bool, m+1) 21 | for i := 0; i < len(f); i++ { 22 | f[i] = make([]bool, n+1) 23 | } 24 | f[0][0] = true 25 | for i := 0; i <= m; i++ { 26 | for j := 1; j <= n; j++ { 27 | if p[j-1] == '*' { 28 | f[i][j] = f[i][j] || f[i][j-2] 29 | if matches(i, j-1) { 30 | f[i][j] = f[i][j] || f[i-1][j] 31 | } 32 | } else if matches(i, j) { 33 | f[i][j] = f[i][j] || f[i-1][j-1] 34 | } 35 | } 36 | } 37 | return f[m][n] 38 | } 39 | 40 | // @lc code=end 41 | 42 | -------------------------------------------------------------------------------- /My-Leetcode/Go/102.二叉树的层序遍历.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=102 lang=golang 3 | * 4 | * [102] 二叉树的层序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | type Node struct { 17 | Ptr *TreeNode 18 | Depth int 19 | } 20 | 21 | func levelOrder(root *TreeNode) [][]int { 22 | res := make([][]int, 0) 23 | if root == nil { 24 | return res 25 | } 26 | queue := make([]Node, 0) 27 | queue = append(queue, Node{root, 0}) 28 | curLevelNodes := make([]int, 0) 29 | curDepth, index := 0, 0 30 | for index < len(queue) { 31 | cur := queue[index] 32 | if curDepth != cur.Depth { 33 | curDepth = cur.Depth 34 | res = append(res, curLevelNodes) 35 | curLevelNodes = make([]int, 0) 36 | } 37 | curLevelNodes = append(curLevelNodes, cur.Ptr.Val) 38 | 39 | if cur.Ptr.Left != nil { 40 | queue = append(queue, Node{cur.Ptr.Left, cur.Depth + 1}) 41 | } 42 | if cur.Ptr.Right != nil { 43 | queue = append(queue, Node{cur.Ptr.Right, cur.Depth + 1}) 44 | } 45 | index += 1 46 | } 47 | res = append(res, curLevelNodes) 48 | return res 49 | } 50 | 51 | // @lc code=end 52 | 53 | -------------------------------------------------------------------------------- /My-Leetcode/Go/1028.从先序遍历还原二叉树.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1028 lang=golang 3 | * 4 | * [1028] 从先序遍历还原二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func recoverFromPreorder(traversal string) *TreeNode { 17 | 18 | } 19 | // @lc code=end 20 | 21 | -------------------------------------------------------------------------------- /My-Leetcode/Go/103.二叉树的锯齿形层序遍历.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=103 lang=golang 3 | * 4 | * [103] 二叉树的锯齿形层序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func zigzagLevelOrder(root *TreeNode) [][]int { 17 | if root == nil { 18 | return nil 19 | } 20 | ret := make([][]int, 0) 21 | queue := make([]*TreeNode, 0) 22 | queue = append(queue, root) 23 | count := 0 24 | for len(queue) > 0 { 25 | res := make([]int, 0) 26 | tmp := make([]*TreeNode, 0) 27 | for i := 0; i < len(queue); i++ { 28 | res = append(res, queue[i].Val) 29 | if queue[i].Left != nil { 30 | tmp = append(tmp, queue[i].Left) 31 | } 32 | if queue[i].Right != nil { 33 | tmp = append(tmp, queue[i].Right) 34 | } 35 | } 36 | if count%2 == 1 { 37 | res = reverseSlice(res) 38 | } 39 | count += 1 40 | ret = append(ret, res) 41 | queue = tmp 42 | } 43 | return ret 44 | } 45 | 46 | func reverseSlice(s []int) []int { 47 | for i := 0; i < len(s)/2; i++ { 48 | s[i], s[len(s)-i-1] = s[len(s)-i-1], s[i] 49 | } 50 | return s 51 | } 52 | 53 | // @lc code=end 54 | 55 | -------------------------------------------------------------------------------- /My-Leetcode/Go/107.二叉树的层序遍历-ii.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=107 lang=golang 3 | * 4 | * [107] 二叉树的层序遍历 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | type Node struct { 17 | Ptr *TreeNode 18 | Depth int 19 | } 20 | 21 | func levelOrderBottom(root *TreeNode) [][]int { 22 | res := make([][]int, 0) 23 | if root == nil { 24 | return res 25 | } 26 | queue := make([]Node, 0) 27 | queue = append(queue, Node{root, 0}) 28 | curLevelNodes := make([]int, 0) 29 | curDepth, index := 0, 0 30 | for index < len(queue) { 31 | cur := queue[index] 32 | if curDepth != cur.Depth { 33 | curDepth = cur.Depth 34 | res = append(res, curLevelNodes) 35 | curLevelNodes = make([]int, 0) 36 | } 37 | curLevelNodes = append(curLevelNodes, cur.Ptr.Val) 38 | 39 | if cur.Ptr.Left != nil { 40 | queue = append(queue, Node{cur.Ptr.Left, cur.Depth + 1}) 41 | } 42 | if cur.Ptr.Right != nil { 43 | queue = append(queue, Node{cur.Ptr.Right, cur.Depth + 1}) 44 | } 45 | index += 1 46 | } 47 | res = append(res, curLevelNodes) 48 | 49 | for i := 0; i <= len(res)/2-1; i++ { 50 | res[i], res[len(res)-i-1] = res[len(res)-i-1], res[i] 51 | } 52 | return res 53 | } 54 | 55 | // @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /My-Leetcode/Go/1143.最长公共子序列.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1143 lang=golang 3 | * 4 | * [1143] 最长公共子序列 5 | */ 6 | 7 | // @lc code=start 8 | func longestCommonSubsequence(text1, text2 string) int { 9 | m, n := len(text1), len(text2) 10 | dp := make([][]int, m+1) 11 | for i := range dp { 12 | dp[i] = make([]int, n+1) 13 | } 14 | for i, c1 := range text1 { 15 | for j, c2 := range text2 { 16 | if c1 == c2 { 17 | dp[i+1][j+1] = dp[i][j] + 1 18 | } else { 19 | dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]) 20 | } 21 | } 22 | } 23 | return dp[m][n] 24 | } 25 | 26 | func max(a, b int) int { 27 | if a > b { 28 | return a 29 | } 30 | return b 31 | } 32 | 33 | // @lc code=end 34 | 35 | -------------------------------------------------------------------------------- /My-Leetcode/Go/121.买卖股票的最佳时机.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=121 lang=golang 3 | * 4 | * [121] 买卖股票的最佳时机 5 | */ 6 | 7 | // @lc code=start 8 | func maxProfit(prices []int) int { 9 | if len(prices) <= 1 { 10 | return 0 11 | } 12 | var min int = prices[0] 13 | var profit int = 0 14 | for i := 1; i < len(prices); i++ { 15 | if prices[i] < min { 16 | min = prices[i] 17 | } 18 | if prices[i]-min > profit { 19 | profit = prices[i] - min 20 | } 21 | } 22 | return profit 23 | } 24 | 25 | // @lc code=end 26 | 27 | -------------------------------------------------------------------------------- /My-Leetcode/Go/14.最长公共前缀.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=14 lang=golang 3 | * 4 | * [14] 最长公共前缀 5 | */ 6 | 7 | // @lc code=start 8 | func longestCommonPrefix(strs []string) string { 9 | var count int = -1 10 | var flag bool = true 11 | for flag { 12 | count += 1 13 | var c byte 14 | if count < len(strs[0]) { 15 | c = strs[0][count] 16 | } else { 17 | break 18 | } 19 | for i := 1; i < len(strs); i++ { 20 | if !(count < len(strs[i]) && strs[i][count] == c) { 21 | flag = false 22 | break 23 | } 24 | } 25 | } 26 | return strs[0][:count] 27 | } 28 | 29 | // @lc code=end 30 | 31 | -------------------------------------------------------------------------------- /My-Leetcode/Go/141.环形链表.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=141 lang=golang 3 | * 4 | * [141] 环形链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func hasCycle(head *ListNode) bool { 16 | if head == nil || head.Next == nil { 17 | return false 18 | } 19 | // 快慢指针 快指针追赶上慢指针则说明有圈 20 | slow, fast := head, head.Next 21 | for fast != slow { 22 | if fast == nil || fast.Next == nil { 23 | return false 24 | } 25 | slow = slow.Next 26 | fast = fast.Next.Next 27 | } 28 | return true 29 | } 30 | 31 | // @lc code=end 32 | 33 | -------------------------------------------------------------------------------- /My-Leetcode/Go/15.三数之和.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=15 lang=golang 3 | * 4 | * [15] 三数之和 5 | */ 6 | 7 | // @lc code=start 8 | func threeSum(nums []int) [][]int { 9 | n := len(nums) 10 | sort.Ints(nums) // 排序 11 | res := make([][]int, 0) 12 | for x := 0; x < n-2; x++ { 13 | if nums[x] > 0 { 14 | break 15 | } 16 | if x > 0 && nums[x] == nums[x-1] { 17 | continue 18 | } 19 | y := x + 1 20 | z := n - 1 21 | for y < z { 22 | if nums[x]+nums[y]+nums[z] == 0 { 23 | res = append(res, []int{nums[x], nums[y], nums[z]}) 24 | y += 1 25 | for y < z && nums[y-1] == nums[y] { 26 | y += 1 27 | } 28 | } else if nums[x]+nums[y]+nums[z] > 0 { 29 | z -= 1 30 | for y < z && nums[z+1] == nums[z] { 31 | z -= 1 32 | } 33 | } else if nums[x]+nums[y]+nums[z] < 0 { 34 | y += 1 35 | for y < z && nums[y-1] == nums[y] { 36 | y += 1 37 | } 38 | } 39 | } 40 | } 41 | return res 42 | } 43 | 44 | // @lc code=end 45 | 46 | -------------------------------------------------------------------------------- /My-Leetcode/Go/151.翻转字符串里的单词.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=151 lang=golang 3 | * 4 | * [151] 翻转字符串里的单词 5 | */ 6 | 7 | // @lc code=start 8 | // 使用go库函数翻转 9 | func reverseWords(s string) string { 10 | res := strings.Fields(s) 11 | length := len(res) 12 | for i := 0; i < length/2; i++ { 13 | res[i], res[length-1-i] = res[length-1-i], res[i] 14 | } 15 | return strings.Join(res, " ") 16 | } 17 | 18 | // @lc code=end 19 | 20 | -------------------------------------------------------------------------------- /My-Leetcode/Go/169.多数元素.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=169 lang=golang 3 | * 4 | * [169] 多数元素 5 | */ 6 | 7 | // @lc code=start 8 | func majorityElement(nums []int) int { 9 | // Boyer-Moore 10 | count := 0 11 | candidate := 0 12 | 13 | for _, num := range nums { 14 | if count == 0 { 15 | candidate = num 16 | } 17 | if num == candidate { 18 | count += 1 19 | } else { 20 | count -= 1 21 | } 22 | } 23 | 24 | return candidate 25 | } 26 | 27 | // @lc code=end 28 | 29 | -------------------------------------------------------------------------------- /My-Leetcode/Go/19.删除链表的倒数第-n-个结点.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=19 lang=golang 3 | * 4 | * [19] 删除链表的倒数第 N 个结点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func removeNthFromEnd(head *ListNode, n int) *ListNode { 16 | nullHead := &ListNode{} 17 | node := nullHead 18 | node.Next = head 19 | 20 | ptr := head 21 | for n > 0 { 22 | n -= 1 23 | ptr = ptr.Next 24 | } 25 | for ptr != nil { 26 | ptr = ptr.Next 27 | node = node.Next 28 | } 29 | node.Next = node.Next.Next 30 | return nullHead.Next 31 | } 32 | 33 | // @lc code=end 34 | 35 | -------------------------------------------------------------------------------- /My-Leetcode/Go/195.第十行.go: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/My-Leetcode/Go/195.第十行.go -------------------------------------------------------------------------------- /My-Leetcode/Go/2.两数相加.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2 lang=golang 3 | * 4 | * [2] 两数相加 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func addTwoNumbers(l1 *ListNode, l2 *ListNode) (head *ListNode) { 16 | var value, carry int 17 | var x1, x2 int 18 | var tail *ListNode 19 | for l1 != nil || l2 != nil { 20 | if l1 == nil { 21 | x1 = 0 22 | } else { 23 | x1 = l1.Val 24 | l1 = l1.Next 25 | } 26 | if l2 == nil { 27 | x2 = 0 28 | } else { 29 | x2 = l2.Val 30 | l2 = l2.Next 31 | } 32 | value, carry = (x1+x2+carry)%10, (x1+x2+carry)/10 33 | fmt.Println(value) 34 | if head == nil { 35 | head = &ListNode{Val: value} 36 | tail = head 37 | } else { 38 | tail.Next = &ListNode{Val: value} 39 | tail = tail.Next 40 | } 41 | } 42 | if carry > 0 { 43 | tail.Next = &ListNode{Val: carry} 44 | } 45 | return 46 | } 47 | 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /My-Leetcode/Go/20.有效的括号.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=20 lang=golang 3 | * 4 | * [20] 有效的括号 5 | */ 6 | 7 | // @lc code=start 8 | func isValid(s string) bool { 9 | stack := []byte{} 10 | pairs := map[byte]byte{ 11 | ')': '(', 12 | ']': '[', 13 | '}': '{', 14 | } 15 | for i := 0; i < len(s); i++ { 16 | if pair, ok := pairs[s[i]]; ok { 17 | if len(stack) == 0 || stack[len(stack)-1] != pair { 18 | return false 19 | } 20 | stack = stack[:len(stack)-1] 21 | } else { 22 | stack = append(stack, s[i]) 23 | } 24 | } 25 | return len(stack) == 0 26 | } 27 | 28 | // @lc code=end 29 | 30 | -------------------------------------------------------------------------------- /My-Leetcode/Go/206.反转链表.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=206 lang=golang 3 | * 4 | * [206] 反转链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func reverseList(head *ListNode) *ListNode { 16 | if head == nil { 17 | return nil 18 | } 19 | if head.Next == nil { 20 | return head 21 | } 22 | next := head.Next 23 | head.Next = nil 24 | newHead := reverseList(next) 25 | next.Next = head 26 | 27 | return newHead 28 | } 29 | 30 | // @lc code=end 31 | 32 | -------------------------------------------------------------------------------- /My-Leetcode/Go/208.实现-trie-前缀树.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=208 lang=golang 3 | * 4 | * [208] 实现 Trie (前缀树) 5 | */ 6 | 7 | // @lc code=start 8 | type Trie struct { 9 | // 每个字母都对应一个子节点 10 | children [26]*Trie 11 | isEnd bool 12 | } 13 | 14 | func Constructor() Trie { 15 | return Trie{} 16 | } 17 | 18 | func (t *Trie) Insert(word string) { 19 | node := t 20 | for _, ch := range word { 21 | ch -= 'a' 22 | if node.children[ch] == nil { 23 | node.children[ch] = &Trie{} 24 | } 25 | node = node.children[ch] 26 | } 27 | node.isEnd = true 28 | } 29 | 30 | func (t *Trie) SearchPrefix(prefix string) *Trie { 31 | node := t 32 | for _, ch := range prefix { 33 | ch -= 'a' 34 | if node.children[ch] == nil { 35 | return nil 36 | } 37 | node = node.children[ch] 38 | } 39 | return node 40 | } 41 | 42 | func (t *Trie) Search(word string) bool { 43 | node := t.SearchPrefix(word) 44 | return node != nil && node.isEnd 45 | } 46 | 47 | func (t *Trie) StartsWith(prefix string) bool { 48 | return t.SearchPrefix(prefix) != nil 49 | } 50 | 51 | /** 52 | * Your Trie object will be instantiated and called as such: 53 | * obj := Constructor(); 54 | * obj.Insert(word); 55 | * param_2 := obj.Search(word); 56 | * param_3 := obj.StartsWith(prefix); 57 | */ 58 | // @lc code=end 59 | 60 | -------------------------------------------------------------------------------- /My-Leetcode/Go/21.合并两个有序链表.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=21 lang=golang 3 | * 4 | * [21] 合并两个有序链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { 16 | if l1 == nil { 17 | return l2 18 | } else if l2 == nil { 19 | return l1 20 | } 21 | 22 | if l1.Val < l2.Val { 23 | l1.Next = mergeTwoLists(l1.Next, l2) 24 | return l1 25 | } else { 26 | l2.Next = mergeTwoLists(l1, l2.Next) 27 | return l2 28 | } 29 | } 30 | 31 | // @lc code=end 32 | 33 | -------------------------------------------------------------------------------- /My-Leetcode/Go/222.完全二叉树的节点个数.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=222 lang=golang 3 | * 4 | * [222] 完全二叉树的节点个数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func countNodes(root *TreeNode) int { 17 | countLevel := func(root *TreeNode) int { 18 | level := 0 19 | for root != nil { 20 | root = root.Left 21 | level += 1 22 | } 23 | return level 24 | } 25 | if root == nil { 26 | return 0 27 | } 28 | leftLevel := countLevel(root.Left) 29 | rightLevel := countLevel(root.Right) 30 | // 如果左深度等于右深度,则左一定为满二叉树 31 | if leftLevel == rightLevel { 32 | return countNodes(root.Right) + (1< 0 { 53 | val := heap.Pop(listNodes).(*ListNode) // 栈顶推出元素 54 | cur.Next = val 55 | if val.Next != nil { 56 | heap.Push(listNodes, val.Next) 57 | } 58 | cur = cur.Next 59 | } 60 | return head.Next 61 | } 62 | 63 | // @lc code=end 64 | 65 | -------------------------------------------------------------------------------- /My-Leetcode/Go/235.二叉搜索树的最近公共祖先.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=235 lang=golang 3 | * 4 | * [235] 二叉搜索树的最近公共祖先 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | 17 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 18 | var getPath = func(root, p *TreeNode) []*TreeNode { 19 | res := []*TreeNode{} 20 | for { 21 | res = append(res, root) 22 | if root.Val == p.Val { 23 | break 24 | } else if root.Val > p.Val { 25 | root = root.Left 26 | } else { 27 | root = root.Right 28 | } 29 | } 30 | return res 31 | } 32 | 33 | path1 := getPath(root, p) 34 | path2 := getPath(root, q) 35 | var i int = 0 36 | for i < len(path1) && i < len(path2) { 37 | if path1[i].Val == path2[i].Val { 38 | i += 1 39 | } else { 40 | break 41 | } 42 | } 43 | return path1[i-1] 44 | 45 | } 46 | 47 | // @lc code=end 48 | 49 | -------------------------------------------------------------------------------- /My-Leetcode/Go/236.二叉树的最近公共祖先.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=236 lang=golang 3 | * 4 | * [236] 二叉树的最近公共祖先 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 17 | if root == nil { 18 | return nil 19 | } 20 | if root.Val == p.Val || root.Val == q.Val { 21 | return root 22 | } else { 23 | left := lowestCommonAncestor(root.Left, p, q) 24 | right := lowestCommonAncestor(root.Right, p, q) 25 | if left == nil { 26 | return right 27 | } else if right == nil { 28 | return left 29 | } else { 30 | return root 31 | } 32 | } 33 | } 34 | 35 | // @lc code=end 36 | 37 | -------------------------------------------------------------------------------- /My-Leetcode/Go/237.删除链表中的节点.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=237 lang=golang 3 | * 4 | * [237] 删除链表中的节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func deleteNode(node *ListNode) { 16 | nextPtr := node.Next 17 | node.Val = nextPtr.Val 18 | node.Next = nextPtr.Next 19 | } 20 | 21 | // @lc code=end 22 | 23 | -------------------------------------------------------------------------------- /My-Leetcode/Go/239.滑动窗口最大值.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=239 lang=golang 3 | * 4 | * [239] 滑动窗口最大值 5 | */ 6 | 7 | // @lc code=start 8 | func maxSlidingWindow(nums []int, k int) []int { 9 | res := make([]int, len(nums)-k+1) 10 | queue := make(monoQueue, 0) 11 | 12 | i := 0 13 | for i = 0; i < k; i++ { 14 | queue = queue.enqueue(pair{nums[i], i}) 15 | } 16 | res[0] = queue[0].num 17 | 18 | for j := 1; i < len(nums); i, j = i+1, j+1 { 19 | // j 指向滑动窗口当前第一个,i指向滑动窗口的下一个 20 | // 滑动窗口加入新元素 21 | queue = queue.enqueue(pair{nums[i], i}) 22 | // 如果队列头不是新元素,将它移除 23 | if queue[0].index == j-1 { 24 | queue = queue.dequeue() 25 | } 26 | res[j] = queue[0].num 27 | } 28 | 29 | return res 30 | } 31 | 32 | type monoQueue []pair 33 | type pair struct { 34 | num int 35 | index int 36 | } 37 | 38 | // 入队 把小于当前元素的都挤掉 39 | func (queue monoQueue) enqueue(elem pair) monoQueue { 40 | i := 0 41 | for i = len(queue) - 1; i >= 0; i-- { //找到插入位置 42 | if queue[i].num > elem.num { 43 | break 44 | } 45 | } 46 | queue = queue[:i+1] 47 | return append(queue, elem) 48 | } 49 | 50 | //出队,去掉队首元素 51 | func (queue monoQueue) dequeue() monoQueue { 52 | return queue[1:] 53 | } 54 | 55 | // @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /My-Leetcode/Go/24.两两交换链表中的节点.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=24 lang=golang 3 | * 4 | * [24] 两两交换链表中的节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func swapPairs(head *ListNode) *ListNode { 16 | 17 | } 18 | // @lc code=end 19 | 20 | -------------------------------------------------------------------------------- /My-Leetcode/Go/25.k-个一组翻转链表.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=25 lang=golang 3 | * 4 | * [25] K 个一组翻转链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func reverseKGroup(head *ListNode, k int) *ListNode { 16 | if head == nil { 17 | return nil 18 | } 19 | var res *ListNode = head 20 | var flag int = 0 21 | var last *ListNode // 上一组的最后一个节点 22 | ptr1, ptr2 := head, head 23 | for { 24 | counter := 0 25 | for counter < k && ptr2 != nil { 26 | ptr2 = ptr2.Next 27 | counter += 1 28 | } 29 | if counter < k { 30 | break 31 | } 32 | newHead := reverseNodes(ptr1, ptr2) 33 | if flag == 0 { 34 | res = newHead 35 | flag = 1 36 | } 37 | if last != nil { 38 | last.Next = newHead 39 | } 40 | ptr1.Next = ptr2 41 | last, ptr1 = ptr1, ptr2 42 | } 43 | return res 44 | } 45 | 46 | func reverseNodes(start, end *ListNode) *ListNode { 47 | if start.Next == end { 48 | return start 49 | } 50 | next := start.Next 51 | newHead := reverseNodes(next, end) 52 | next.Next = start 53 | start.Next = nil 54 | return newHead 55 | } 56 | 57 | func printNodes(start *ListNode) { 58 | for start != nil { 59 | start = start.Next 60 | } 61 | fmt.Println() 62 | } 63 | 64 | // @lc code=end 65 | 66 | -------------------------------------------------------------------------------- /My-Leetcode/Go/258.各位相加.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=258 lang=golang 3 | * 4 | * [258] 各位相加 5 | */ 6 | 7 | // @lc code=start 8 | func addDigits(num int) int { 9 | if num == 0 { 10 | return 0 11 | } 12 | 13 | res := num % 9 14 | if res == 0 { 15 | return 9 16 | } 17 | 18 | return res 19 | } 20 | 21 | // @lc code=end 22 | 23 | -------------------------------------------------------------------------------- /My-Leetcode/Go/26.删除有序数组中的重复项.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=26 lang=golang 3 | * 4 | * [26] 删除有序数组中的重复项 5 | */ 6 | 7 | // @lc code=start 8 | func removeDuplicates(nums []int) int { 9 | if len(nums) == 0 { 10 | return 0 11 | } 12 | count := 0 13 | slow, fast := 0, 0 14 | for fast < len(nums) { 15 | for fast+1 < len(nums) && nums[fast] == nums[fast+1] { 16 | fast += 1 17 | } 18 | nums[slow] = nums[fast] 19 | fmt.Println(nums[slow]) 20 | fast += 1 21 | slow += 1 22 | count += 1 23 | } 24 | return count 25 | } 26 | 27 | // @lc code=end 28 | 29 | -------------------------------------------------------------------------------- /My-Leetcode/Go/292.nim-游戏.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=292 lang=golang 3 | * 4 | * [292] Nim 游戏 5 | */ 6 | 7 | // @lc code=start 8 | func canWinNim(n int) bool { 9 | return n%4 != 0 10 | } 11 | 12 | // @lc code=end 13 | 14 | -------------------------------------------------------------------------------- /My-Leetcode/Go/297.二叉树的序列化与反序列化.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=297 lang=golang 3 | * 4 | * [297] 二叉树的序列化与反序列化 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | 17 | type Codec struct { 18 | } 19 | 20 | func Constructor() Codec { 21 | return Codec{} 22 | } 23 | 24 | // Serializes a tree to a single string. 25 | func (this *Codec) serialize(root *TreeNode) string { 26 | if root == nil { 27 | return "nil" 28 | } 29 | return strconv.Itoa(root.Val) + "," + this.serialize(root.Left) + "," + this.serialize(root.Right) 30 | } 31 | 32 | // Deserializes your encoded data to tree. 33 | func (this *Codec) deserialize(data string) *TreeNode { 34 | list := strings.Split(data, ",") 35 | return buildTree(&list) 36 | } 37 | 38 | func buildTree(list *[]string) *TreeNode { 39 | rootVal := (*list)[0] 40 | *list = (*list)[1:] 41 | if rootVal == "nil" { 42 | return nil 43 | } 44 | Val, _ := strconv.Atoi(rootVal) 45 | root := &TreeNode{Val: Val} 46 | root.Left = buildTree(list) 47 | root.Right = buildTree(list) 48 | return root 49 | } 50 | 51 | /** 52 | * Your Codec object will be instantiated and called as such: 53 | * ser := Constructor(); 54 | * deser := Constructor(); 55 | * data := ser.serialize(root); 56 | * ans := deser.deserialize(data); 57 | */ 58 | // @lc code=end 59 | 60 | -------------------------------------------------------------------------------- /My-Leetcode/Go/3.无重复字符的最长子串.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=3 lang=golang 3 | * 4 | * [3] 无重复字符的最长子串 5 | */ 6 | 7 | // @lc code=start 8 | func lengthOfLongestSubstring(s string) int { 9 | myMap := map[byte]int{} 10 | var maxLen, curLen int 11 | for i := 0; i < len(s); i++ { 12 | if index, ok := myMap[s[i]]; ok { 13 | if curLen > maxLen { 14 | maxLen = curLen 15 | } 16 | i = index 17 | myMap = map[byte]int{} 18 | curLen = 0 19 | } else { 20 | curLen += 1 21 | myMap[s[i]] = i 22 | } 23 | } 24 | if curLen > maxLen { 25 | maxLen = curLen 26 | } 27 | return maxLen 28 | } 29 | 30 | // @lc code=end 31 | 32 | -------------------------------------------------------------------------------- /My-Leetcode/Go/33.搜索旋转排序数组.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=33 lang=golang 3 | * 4 | * [33] 搜索旋转排序数组 5 | */ 6 | 7 | // @lc code=start 8 | func search(nums []int, target int) int { 9 | left, right := 0, len(nums)-1 10 | for left <= right { 11 | mid := (left + right) / 2 12 | if nums[mid] == target { 13 | return mid 14 | } 15 | // 判断mid落在哪一侧 16 | if nums[mid] >= nums[left] { 17 | // 判断向哪一边搜索 18 | if nums[mid] > target && target >= nums[left] { 19 | right = mid - 1 20 | } else { 21 | left = mid + 1 22 | } 23 | } else { 24 | if nums[mid] < target && target <= nums[right] { 25 | left = mid + 1 26 | } else { 27 | right = mid - 1 28 | } 29 | } 30 | } 31 | return -1 32 | } 33 | 34 | // @lc code=end 35 | 36 | -------------------------------------------------------------------------------- /My-Leetcode/Go/342.4-的幂.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=342 lang=golang 3 | * 4 | * [342] 4的幂 5 | */ 6 | 7 | // @lc code=start 8 | func isPowerOfFour(n int) bool { 9 | 10 | } 11 | // @lc code=end 12 | 13 | -------------------------------------------------------------------------------- /My-Leetcode/Go/347.前-k-个高频元素.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=347 lang=golang 3 | * 4 | * [347] 前 K 个高频元素 5 | */ 6 | 7 | // @lc code=start 8 | 9 | type node struct { 10 | Key int 11 | Value int 12 | } 13 | 14 | func topKFrequent(nums []int, k int) (res []int) { 15 | m := make(map[int]int) 16 | for _, num := range nums { 17 | m[num] += 1 18 | } 19 | nodes := make([]node, 0) 20 | for key, value := range m { 21 | nodes = append(nodes, node{key, value}) 22 | } 23 | 24 | nodes = heapSort(nodes, len(nodes)-1, k) 25 | for i := 1; i <= k; i++ { 26 | res = append(res, nodes[len(nodes)-i].Key) 27 | } 28 | return 29 | } 30 | 31 | func maxHeap(nums []node, root, end int) []node { 32 | left := 2*root + 1 33 | right := 2*root + 2 34 | largest := root 35 | if left <= end && nums[left].Value > nums[largest].Value { 36 | largest = left 37 | } 38 | if right <= end && nums[right].Value > nums[largest].Value { 39 | largest = right 40 | } 41 | // 向下递归调整 42 | if largest != root { 43 | nums[root], nums[largest] = nums[largest], nums[root] 44 | nums = maxHeap(nums, largest, end) 45 | } 46 | return nums 47 | } 48 | 49 | func buildHeap(nums []node) []node { 50 | for i := len(nums) - 1; i >= 0; i-- { 51 | maxHeap(nums, i, len(nums)-1) 52 | } 53 | return nums 54 | } 55 | 56 | func heapSort(nums []node, end, k int) []node { 57 | // 将数组构建为最大堆 58 | nums = buildHeap(nums) 59 | for k > 0 { 60 | k -= 1 61 | // 交换头尾位置 62 | nums[0], nums[end] = nums[end], nums[0] 63 | end -= 1 64 | //恢复为最大堆 65 | nums = maxHeap(nums, 0, end) 66 | } 67 | return nums 68 | } 69 | 70 | // @lc code=end 71 | 72 | -------------------------------------------------------------------------------- /My-Leetcode/Go/380.o-1-时间插入、删除和获取随机元素.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=380 lang=golang 3 | * 4 | * [380] O(1) 时间插入、删除和获取随机元素 5 | */ 6 | 7 | // @lc code=start 8 | type RandomizedSet struct { 9 | 10 | } 11 | 12 | 13 | /** Initialize your data structure here. */ 14 | func Constructor() RandomizedSet { 15 | 16 | } 17 | 18 | 19 | /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ 20 | func (this *RandomizedSet) Insert(val int) bool { 21 | 22 | } 23 | 24 | 25 | /** Removes a value from the set. Returns true if the set contained the specified element. */ 26 | func (this *RandomizedSet) Remove(val int) bool { 27 | 28 | } 29 | 30 | 31 | /** Get a random element from the set. */ 32 | func (this *RandomizedSet) GetRandom() int { 33 | 34 | } 35 | 36 | 37 | /** 38 | * Your RandomizedSet object will be instantiated and called as such: 39 | * obj := Constructor(); 40 | * param_1 := obj.Insert(val); 41 | * param_2 := obj.Remove(val); 42 | * param_3 := obj.GetRandom(); 43 | */ 44 | // @lc code=end 45 | 46 | -------------------------------------------------------------------------------- /My-Leetcode/Go/4.寻找两个正序数组的中位数.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=4 lang=golang 3 | * 4 | * [4] 寻找两个正序数组的中位数 5 | */ 6 | 7 | // @lc code=start 8 | func findMedianSortedArrays(nums1 []int, nums2 []int) float64 { 9 | n := len(nums1) + len(nums2) 10 | curNum := 0 11 | var i, j int = 0, 0 12 | var last, cur float64 13 | for i < len(nums1) || j < len(nums2) { 14 | var n1, n2 float64 15 | last = cur 16 | if i == len(nums1) { 17 | n1 = math.Inf(1) 18 | } else { 19 | n1 = float64(nums1[i]) 20 | } 21 | if j == len(nums2) { 22 | n2 = math.Inf(1) 23 | } else { 24 | n2 = float64(nums2[j]) 25 | } 26 | 27 | if n1 < n2 { 28 | cur = n1 29 | i += 1 30 | } else { 31 | cur = n2 32 | j += 1 33 | } 34 | curNum += 1 35 | if curNum > n/2 { 36 | if n%2 == 0 { // 若总数为偶数 37 | return (last + cur) / 2.0 38 | } else { 39 | return cur 40 | } 41 | } 42 | } 43 | return 0.0 44 | } 45 | 46 | // @lc code=end 47 | 48 | -------------------------------------------------------------------------------- /My-Leetcode/Go/402.移掉k位数字.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=402 lang=golang 3 | * 4 | * [402] 移掉K位数字 5 | */ 6 | 7 | // @lc code=start 8 | func removeKdigits(num string, k int) string { 9 | stack := []byte{} 10 | for i := range num { 11 | digit := num[i] 12 | for k > 0 && len(stack) > 0 && digit < stack[len(stack)-1] { 13 | stack = stack[:len(stack)-1] 14 | k-- 15 | } 16 | stack = append(stack, digit) 17 | } 18 | stack = stack[:len(stack)-k] 19 | ans := strings.TrimLeft(string(stack), "0") 20 | if ans == "" { 21 | ans = "0" 22 | } 23 | return ans 24 | } 25 | 26 | // @lc code=end 27 | 28 | -------------------------------------------------------------------------------- /My-Leetcode/Go/42.接雨水.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=42 lang=golang 3 | * 4 | * [42] 接雨水 5 | */ 6 | 7 | // @lc code=start 8 | func trap(height []int) int { 9 | n := len(height) 10 | if n < 3 { 11 | return 0 12 | } 13 | leftMax := make([]int, n) 14 | rightMax := make([]int, n) 15 | leftMax[0] = height[0] 16 | for i := 1; i < n; i++ { 17 | leftMax[i] = max(leftMax[i-1], height[i]) 18 | } 19 | rightMax[n-1] = height[n-1] 20 | for i := n - 2; i >= 0; i-- { 21 | rightMax[i] = max(rightMax[i+1], height[i]) 22 | } 23 | 24 | count := 0 25 | for i := 0; i < n; i++ { 26 | count += min(leftMax[i], rightMax[i]) - height[i] 27 | } 28 | return count 29 | } 30 | func min(a, b int) int { 31 | if a < b { 32 | return a 33 | } 34 | return b 35 | } 36 | 37 | func max(a, b int) int { 38 | if a > b { 39 | return a 40 | } 41 | return b 42 | } 43 | 44 | // @lc code=end 45 | 46 | -------------------------------------------------------------------------------- /My-Leetcode/Go/457.环形数组是否存在循环.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=457 lang=golang 3 | * 4 | * [457] 环形数组是否存在循环 5 | */ 6 | 7 | // @lc code=start 8 | func circularArrayLoop(nums []int) bool { 9 | 10 | } 11 | // @lc code=end 12 | 13 | -------------------------------------------------------------------------------- /My-Leetcode/Go/5.最长回文子串.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=5 lang=golang 3 | * 4 | * [5] 最长回文子串 5 | */ 6 | 7 | // @lc code=start 8 | func longestPalindrome(s string) string { 9 | n := len(s) 10 | if n == 0 { 11 | return "" 12 | } 13 | 14 | var maxLen int 15 | var res string 16 | matrix := make([][]int, n) 17 | for i := 0; i < n; i++ { 18 | matrix[i] = make([]int, n) 19 | } 20 | 21 | // 动态规划 22 | for l := 1; l <= n; l++ { // 遍历子串长度 23 | for i := 0; i < n-l+1; i++ { 24 | j := i + l - 1 //计算右指针 25 | if s[i] == s[j] { 26 | if i+1 > j-1 { 27 | matrix[i][j] = 1 28 | } else { 29 | matrix[i][j] = matrix[i+1][j-1] 30 | } 31 | if matrix[i][j] == 1 && j-i+1 > maxLen { 32 | maxLen = j - i + 1 33 | res = s[i : j+1] 34 | } 35 | } 36 | } 37 | } 38 | return res 39 | } 40 | 41 | // @lc code=end 42 | 43 | -------------------------------------------------------------------------------- /My-Leetcode/Go/53.最大子序和.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=53 lang=golang 3 | * 4 | * [53] 最大子序和 5 | */ 6 | 7 | // @lc code=start 8 | func maxSubArray(nums []int) int { 9 | max := nums[0] 10 | for i := 1; i < len(nums); i++ { 11 | if nums[i]+nums[i-1] > nums[i] { 12 | nums[i] += nums[i-1] 13 | } 14 | if nums[i] > max { 15 | max = nums[i] 16 | } 17 | } 18 | return max 19 | } 20 | 21 | // @lc code=end 22 | 23 | -------------------------------------------------------------------------------- /My-Leetcode/Go/55.跳跃游戏.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=55 lang=golang 3 | * 4 | * [55] 跳跃游戏 5 | */ 6 | 7 | // @lc code=start 8 | func canJump(nums []int) bool { 9 | 10 | } 11 | // @lc code=end 12 | 13 | -------------------------------------------------------------------------------- /My-Leetcode/Go/589.n-叉树的前序遍历.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=589 lang=golang 3 | * 4 | * [589] N 叉树的前序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a Node. 10 | * type Node struct { 11 | * Val int 12 | * Children []*Node 13 | * } 14 | */ 15 | 16 | func preorder(root *Node) []int { 17 | res := make([]int, 0) 18 | if root == nil { 19 | return res 20 | } 21 | res = append(res, root.Val) 22 | for i := 0; i < len(root.Children); i++ { 23 | childRes := preorder(root.Children[i]) 24 | res = append(res, childRes...) 25 | } 26 | return res 27 | } 28 | 29 | // @lc code=end 30 | 31 | -------------------------------------------------------------------------------- /My-Leetcode/Go/590.n-叉树的后序遍历.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=590 lang=golang 3 | * 4 | * [590] N 叉树的后序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a Node. 10 | * type Node struct { 11 | * Val int 12 | * Children []*Node 13 | * } 14 | */ 15 | 16 | func postorder(root *Node) []int { 17 | res := make([]int, 0) 18 | if root == nil { 19 | return res 20 | } 21 | for i := 0; i < len(root.Children); i++ { 22 | childRes := postorder(root.Children[i]) 23 | res = append(res, childRes...) 24 | } 25 | res = append(res, root.Val) 26 | return res 27 | } 28 | 29 | // @lc code=end 30 | 31 | -------------------------------------------------------------------------------- /My-Leetcode/Go/6.z-字形变换.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=6 lang=golang 3 | * 4 | * [6] Z 字形变换 5 | */ 6 | 7 | // @lc code=start 8 | func convert(s string, numRows int) string { 9 | 10 | } 11 | // @lc code=end 12 | 13 | -------------------------------------------------------------------------------- /My-Leetcode/Go/617.合并二叉树.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=617 lang=golang 3 | * 4 | * [617] 合并二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode { 17 | if root1 == nil { 18 | return root2 19 | } 20 | if root2 == nil { 21 | return root1 22 | } 23 | root1.Val += root2.Val 24 | root1.Left = mergeTrees(root1.Left, root2.Left) 25 | root1.Right = mergeTrees(root1.Right, root2.Right) 26 | return root1 27 | } 28 | 29 | // @lc code=end 30 | 31 | -------------------------------------------------------------------------------- /My-Leetcode/Go/662.二叉树最大宽度.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=662 lang=golang 3 | * 4 | * [662] 二叉树最大宽度 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | type item struct { 17 | depth int 18 | index int 19 | node *TreeNode 20 | } 21 | 22 | func widthOfBinaryTree(root *TreeNode) int { 23 | if root == nil { 24 | return 0 25 | } 26 | queue := []item{{0, 0, root}} 27 | var i, curDepth int = 0, 0 28 | var maxWidth, left int 29 | for i < len(queue) { 30 | if curDepth != queue[i].depth { 31 | if queue[i-1].index-left+1 > maxWidth { 32 | maxWidth = queue[i-1].index - left + 1 33 | } 34 | curDepth = queue[i].depth 35 | left = queue[i].index 36 | } 37 | if queue[i].node.Left != nil { 38 | queue = append(queue, item{queue[i].depth + 1, 2*queue[i].index + 1, queue[i].node.Left}) 39 | } 40 | if queue[i].node.Right != nil { 41 | queue = append(queue, item{queue[i].depth + 1, 2*queue[i].index + 2, queue[i].node.Right}) 42 | } 43 | i += 1 44 | } 45 | if queue[i-1].index-left+1 > maxWidth { 46 | maxWidth = queue[i-1].index - left + 1 47 | } 48 | return maxWidth 49 | } 50 | 51 | // @lc code=end 52 | 53 | -------------------------------------------------------------------------------- /My-Leetcode/Go/692.前k个高频单词.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=692 lang=golang 3 | * 4 | * [692] 前K个高频单词 5 | */ 6 | 7 | // @lc code=start 8 | func topKFrequent(words []string, k int) []string { 9 | count := make(map[string]int) 10 | for i := 0; i < len(words); i++ { 11 | count[words[i]] += 1 12 | } 13 | uniqueWords := make([]string, 0) 14 | for w := range count { 15 | uniqueWords = append(uniqueWords, w) 16 | } 17 | sort.Slice(uniqueWords, func(i, j int) bool { 18 | s, t := uniqueWords[i], uniqueWords[j] 19 | return count[s] > count[t] || (count[s] == count[t] && s < t) 20 | }) 21 | return uniqueWords[:k] 22 | 23 | } 24 | 25 | // @lc code=end 26 | 27 | -------------------------------------------------------------------------------- /My-Leetcode/Go/695.岛屿的最大面积.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=695 lang=golang 3 | * 4 | * [695] 岛屿的最大面积 5 | */ 6 | 7 | // @lc code=start 8 | type node struct { 9 | i, j int 10 | } 11 | 12 | func maxAreaOfIsland(grid [][]int) int { 13 | bfs := func(grid [][]int, start node) int { 14 | var res, index int = 0, 0 15 | queue := make([]node, 0) 16 | queue = append(queue, node{start.i, start.j}) 17 | grid[start.i][start.j] = 0 18 | for index < len(queue) { 19 | curNode := queue[index] 20 | i, j := curNode.i, curNode.j 21 | res, index = res+1, index+1 22 | 23 | if i-1 >= 0 && grid[i-1][j] == 1 { 24 | queue = append(queue, node{i - 1, j}) 25 | grid[i-1][j] = 0 26 | } 27 | if i+1 < len(grid) && grid[i+1][j] == 1 { 28 | queue = append(queue, node{i + 1, j}) 29 | grid[i+1][j] = 0 30 | } 31 | if j-1 >= 0 && grid[i][j-1] == 1 { 32 | queue = append(queue, node{i, j - 1}) 33 | grid[i][j-1] = 0 34 | } 35 | if j+1 < len(grid[0]) && grid[i][j+1] == 1 { 36 | queue = append(queue, node{i, j + 1}) 37 | grid[i][j+1] = 0 38 | } 39 | } 40 | return res 41 | } 42 | maxArea := 0 43 | for i := 0; i < len(grid); i++ { 44 | for j := 0; j < len(grid[0]); j++ { 45 | if grid[i][j] == 1 { 46 | area := bfs(grid, node{i, j}) 47 | if area > maxArea { 48 | maxArea = area 49 | } 50 | } 51 | } 52 | } 53 | return maxArea 54 | } 55 | 56 | // @lc code=end 57 | 58 | -------------------------------------------------------------------------------- /My-Leetcode/Go/7.整数反转.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=7 lang=golang 3 | * 4 | * [7] 整数反转 5 | */ 6 | 7 | // @lc code=start 8 | func reverse(x int) int { 9 | 10 | } 11 | // @lc code=end 12 | 13 | -------------------------------------------------------------------------------- /My-Leetcode/Go/70.爬楼梯.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=70 lang=golang 3 | * 4 | * [70] 爬楼梯 5 | */ 6 | 7 | // @lc code=start 8 | func climbStairs(n int) int { 9 | res := make([]int, n+1) 10 | 11 | res[0] = 1 12 | res[1] = 1 13 | for i := 2; i <= n; i++ { 14 | res[i] = res[i-1] + res[i-2] 15 | } 16 | return res[n] 17 | } 18 | 19 | // @lc code=end 20 | 21 | -------------------------------------------------------------------------------- /My-Leetcode/Go/700.二叉搜索树中的搜索.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=700 lang=golang 3 | * 4 | * [700] 二叉搜索树中的搜索 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func searchBST(root *TreeNode, val int) *TreeNode { 17 | for root != nil { 18 | if root.Val == val { 19 | return root 20 | } else if root.Val > val { 21 | root = root.Left 22 | } else { 23 | root = root.Right 24 | } 25 | } 26 | return nil 27 | 28 | } 29 | 30 | // @lc code=end 31 | 32 | -------------------------------------------------------------------------------- /My-Leetcode/Go/701.二叉搜索树中的插入操作.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=701 lang=golang 3 | * 4 | * [701] 二叉搜索树中的插入操作 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func insertIntoBST(root *TreeNode, val int) *TreeNode { 17 | if root == nil { 18 | return &TreeNode{val, nil, nil} 19 | } 20 | ret := root 21 | for root != nil { 22 | if root.Val > val { 23 | if root.Left == nil { 24 | root.Left = &TreeNode{val, nil, nil} 25 | return ret 26 | } else { 27 | root = root.Left 28 | } 29 | } else { 30 | if root.Right == nil { 31 | root.Right = &TreeNode{val, nil, nil} 32 | return ret 33 | } else { 34 | root = root.Right 35 | } 36 | } 37 | } 38 | return ret 39 | } 40 | 41 | // @lc code=end 42 | 43 | -------------------------------------------------------------------------------- /My-Leetcode/Go/704.二分查找.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=704 lang=golang 3 | * 4 | * [704] 二分查找 5 | */ 6 | 7 | // @lc code=start 8 | func search(nums []int, target int) int { 9 | l := 0 10 | r := len(nums) - 1 11 | for l < r { 12 | mid := (l + r) / 2 13 | if target <= nums[mid] { 14 | r = mid 15 | } else { 16 | l = mid + 1 17 | } 18 | } 19 | if nums[r] == target { 20 | return r 21 | } 22 | return -1 23 | } 24 | 25 | // @lc code=end 26 | 27 | -------------------------------------------------------------------------------- /My-Leetcode/Go/725.分隔链表.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=725 lang=golang 3 | * 4 | * [725] 分隔链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | func splitListToParts(root *ListNode, k int) []*ListNode { 16 | cur := root 17 | count := 0 18 | for cur != nil { 19 | count += 1 20 | cur = cur.Next 21 | } 22 | num, remainder := count/k, count%k 23 | res := make([]*ListNode, 0) 24 | cur = root 25 | for i := 0; i < k; i++ { 26 | var width int 27 | // 确定这个part的节点数量 28 | if i < remainder { 29 | width = num + 1 30 | } else { 31 | width = num 32 | } 33 | res = append(res, cur) 34 | // cur 向前移动width个单位 35 | for width != 0 && cur != nil { 36 | if width == 1 { 37 | cur, cur.Next = cur.Next, nil 38 | break 39 | } 40 | width -= 1 41 | cur = cur.Next 42 | } 43 | } 44 | return res 45 | 46 | } 47 | 48 | // @lc code=end 49 | 50 | -------------------------------------------------------------------------------- /My-Leetcode/Go/9.回文数.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=9 lang=golang 3 | * 4 | * [9] 回文数 5 | */ 6 | 7 | // @lc code=start 8 | func isPalindrome(x int) bool { 9 | // 特殊情况: 10 | // 如上所述,当 x < 0 时,x 不是回文数。 11 | // 同样地,如果数字的最后一位是 0,为了使该数字为回文, 12 | // 则其第一位数字也应该是 0 13 | // 只有 0 满足这一属性 14 | if x < 0 || (x%10 == 0 && x != 0) { 15 | return false 16 | } 17 | 18 | revertedNumber := 0 19 | for x > revertedNumber { 20 | revertedNumber = revertedNumber*10 + x%10 21 | x /= 10 22 | } 23 | 24 | // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。 25 | // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123, 26 | // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。 27 | return x == revertedNumber || x == revertedNumber/10 28 | } 29 | 30 | // @lc code=end 31 | 32 | -------------------------------------------------------------------------------- /My-Leetcode/Go/98.验证二叉搜索树.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=98 lang=golang 3 | * 4 | * [98] 验证二叉搜索树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * type TreeNode struct { 11 | * Val int 12 | * Left *TreeNode 13 | * Right *TreeNode 14 | * } 15 | */ 16 | func isValidBST(root *TreeNode) bool { 17 | return recursion(root, math.MinInt64, math.MaxInt64) 18 | } 19 | 20 | func recursion(root *TreeNode, lower, upper int) bool { 21 | if root == nil { 22 | return true 23 | } 24 | if root.Val > lower && root.Val < upper { 25 | return recursion(root.Left, lower, root.Val) && recursion(root.Right, root.Val, upper) 26 | } else { 27 | return false 28 | } 29 | } 30 | 31 | // @lc code=end 32 | 33 | -------------------------------------------------------------------------------- /My-Leetcode/Python/11. 盛最多水的容器【双指针】.py: -------------------------------------------------------------------------------- 1 | # 双指针,关键是理解为什么要移动高度小的一边的指针。 2 | # 因为高度高的一边的指针移动会被限制与小的高度,因此移动后装水量一定小于原来,因此移动没有意义 3 | class Solution: 4 | def maxArea(self, height): 5 | res = 0 6 | if len(height)<2: 7 | return 0 8 | i = 0 9 | j = len(height)-1 10 | res = 0 11 | while i bool: 3 | self.bracket = { 4 | "(": ")", 5 | "{": "}", 6 | "[": "]" 7 | } 8 | stack = [] 9 | for c in s: 10 | if self.bracket.get(c, False): 11 | stack.append(c) 12 | else: 13 | if len(stack) > 0 and self.bracket[stack[-1]] == c: 14 | stack = stack[:-1] 15 | else: 16 | return False 17 | if len(stack) > 0: 18 | return False 19 | return True -------------------------------------------------------------------------------- /My-Leetcode/Python/53. 最大子数组和【动态规划】.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums: List[int]) -> int: 3 | res = nums[0] 4 | cur_max = 0 5 | for i in range(len(nums)): 6 | if nums[i] >= cur_max + nums[i]: 7 | cur_max = nums[i] 8 | else: 9 | cur_max += nums[i] 10 | res = max(res, cur_max) 11 | return res 12 | -------------------------------------------------------------------------------- /My-Leetcode/Python/54. 螺旋矩阵【数组】.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def spiralOrder(self, matrix: List[List[int]]) -> List[int]: 3 | res = [] 4 | if len(matrix) <=0 or len(matrix[0]) <= 0: 5 | return res 6 | self.N, self.M = len(matrix), len(matrix[0]) 7 | dist_seq = [[0, 1], [1, 0], [0, -1], [-1, 0]] 8 | 9 | i, j, dist = 0, 0, 0 10 | while True: 11 | res.append(matrix[i][j]) 12 | matrix[i][j] = "/" 13 | next_i, next_j = i + dist_seq[dist][0], j + dist_seq[dist][1] 14 | if not self.legal(next_i,next_j,matrix): 15 | if len(res) == self.N * self.M: 16 | return res 17 | # 换方向 18 | dist = (dist + 1) % len(dist_seq) 19 | next_i, next_j = i + dist_seq[dist][0], j + dist_seq[dist][1] 20 | i, j = next_i, next_j 21 | 22 | def legal(self, i , j, matrix): 23 | if i<0 or i>=self.N or j<0 or j>=self.M or matrix[i][j] == "/": 24 | return False 25 | return True -------------------------------------------------------------------------------- /My-Leetcode/SQL/176. 第二高的薪水.sql: -------------------------------------------------------------------------------- 1 | SELECT DISTINCT 2 | Salary AS SecondHighestSalary 3 | FROM 4 | Employee 5 | ORDER BY Salary DESC 6 | LIMIT 1 OFFSET 1 7 | 8 | -- 然而,如果没有这样的第二最高工资,这个解决方案将被判断为 “错误答案”,因为本表可能只有一项记录。为了克服这个问题,我们可以将其作为临时表。 9 | SELECT 10 | (SELECT DISTINCT 11 | Salary 12 | FROM 13 | Employee 14 | ORDER BY Salary DESC 15 | LIMIT 1 OFFSET 1) AS SecondHighestSalary 16 | ; 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My-Leetcode 2 | 3 | 这是我的Leetcode等OJ平台的题解合集,目前题解使用语言覆盖:C++、Go、Python。 4 | 5 | 题目按照类型进行了分类标签,可以按照需要选取不同难度和类型的题目学习。题目标题包含Leetcode题号,题目有详细的题解和注释,欢迎取用。 6 | 7 | 8 | 9 | # 更新日志 10 | 11 | **2023.8** —— 新增2023春秋招面经验 👉: [:running:](https://github.com/ysyisyourbrother/My-Leetcode/tree/master/%E9%9D%A2%E7%BB%8F) 12 | 13 | **2021.6** —— 新增2021春招面经验。一些题目用Go语言重写 👉: [:running:](https://github.com/ysyisyourbrother/My-Leetcode/tree/master/My-Leetcode) 14 | 15 | **2020.4** —— 新增企业题库和面经模块,分享求职心得与经验 👉: [:running:](https://github.com/ysyisyourbrother/My-Leetcode/tree/master/%E9%9D%A2%E7%BB%8F) 16 | 17 | -------------------------------------------------------------------------------- /数据结构与算法/动态规划/【树&动态规划】扰乱字符串.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/动态规划/【树&动态规划】扰乱字符串.cpp -------------------------------------------------------------------------------- /数据结构与算法/动态规划/广州没有雪-2 .cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/动态规划/广州没有雪-2 .cpp -------------------------------------------------------------------------------- /数据结构与算法/动态规划/最长回文子串.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | string longestPalindrome(string s) { 4 | if(s == "") return ""; 5 | int arr[1000][1000]; 6 | for(int i=0;i& nums) 6 | { 7 | if(nums.size()==0) return true; 8 | int cur_far=0; //目前能到达最远的位置 9 | int index=0;//目前探测到的位置 10 | for(;index<=cur_far&&cur_farcur_far) 13 | cur_far=index+nums[index]; 14 | } 15 | if(cur_far>=nums.size()-1) 16 | { 17 | return true; 18 | } 19 | return false; 20 | } 21 | }; 22 | int main() 23 | { 24 | Solution test; 25 | } -------------------------------------------------------------------------------- /数据结构与算法/动态规划/跳跃游戏II.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int jump(vector& nums) 6 | { 7 | int res; 8 | int time[100000]; 9 | for(int i=0;icur_far) 18 | { 19 | if(index+nums[index]>=nums.size()-1) return time[index]+1; 20 | int i =cur_far+1; 21 | cur_far=index+nums[index]; 22 | for(;i<=cur_far;i++) 23 | { 24 | time[i]=time[index]+1; 25 | } 26 | } 27 | } 28 | return time[nums.size()-1]; 29 | } 30 | }; 31 | int main() 32 | { 33 | Solution test; 34 | } -------------------------------------------------------------------------------- /数据结构与算法/图/dijkstra算法.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/图/dijkstra算法.cpp -------------------------------------------------------------------------------- /数据结构与算法/图/【BFS】Knight Moves .cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | #define Maxsize 150 4 | #define infinity 65536 5 | //骑士周游世界问题 骑士在棋盘上走,每次只能跳一个日字,求从一个格子到另外一个格子最小跳日字次数 6 | struct node 7 | { 8 | int x,y; 9 | int count; 10 | node(int a,int b,int c):x(a),y(b),count(c){} 11 | }; 12 | int Move[8][2]={{1,-2},{2,-1},{2,1},{1,2},//马走日的八个方向. 13 | {-1,2},{-2,1},{-2,-1},{-1,-2}}; 14 | int main() 15 | { 16 | int T; 17 | cin>>T; 18 | while(T--) 19 | { 20 | int ex,ey;//the coordinate of end point 21 | bool chessboard[8][8]; 22 | for(int i=0;i<8;i++) 23 | { 24 | for(int j=0;j<8;j++) 25 | { 26 | chessboard[i][j]=false; 27 | } 28 | } 29 | char str1[3]; 30 | char str2[3]; 31 | scanf("%s%s",str1,str2); 32 | ex=str2[0]-'a'; 33 | ey=str2[1]-'0'-1; 34 | queue que;//the queue of node to do bfs 35 | node tem(str1[0]-'a',str1[1]-'0'-1,0);//build the start node 36 | que.push(tem); 37 | chessboard[tem.x][tem.y]=true; 38 | 39 | while(!que.empty())//begin the bfs algorithm 40 | { 41 | node temp=que.front(); 42 | que.pop(); 43 | if(temp.x==ex&&temp.y==ey) 44 | { 45 | cout<<"To get from "<=0&&x<8&&y>=0&&y<8&&chessboard[x][y]==false) 53 | { 54 | chessboard[x][y]=true; 55 | que.push(node(x,y,temp.count+1)); 56 | } 57 | } 58 | } 59 | 60 | } 61 | } -------------------------------------------------------------------------------- /数据结构与算法/图/【dfs】The Longest Path.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | #define Maxsize 1000 4 | struct Graph 5 | { 6 | vector adj[Maxsize]; 7 | map degree; 8 | }; 9 | void dfs(Graph &g, int s,int &len,int &Max_len,map &visit) 10 | { 11 | visit[s]=1; 12 | len++; 13 | if(g.degree[s]==1) 14 | { 15 | Max_len=Max_len>len?Max_len:len; 16 | } 17 | int i; 18 | for(i=0;i>T; 32 | while(T--) 33 | { 34 | Graph g; 35 | int m; 36 | cin>>m; 37 | if(m==0) 38 | { 39 | cout<<"0"< visit; 44 | map::iterator it; 45 | for(int i=0;i>temp1>>temp2; 48 | g.adj[temp1].push_back(temp2); 49 | g.adj[temp2].push_back(temp1); 50 | visit[temp1]=0; 51 | visit[temp2]=0; 52 | 53 | it = g.degree.find(temp1); 54 | if(it==g.degree.end()) 55 | { 56 | g.degree[temp1]=1; 57 | } 58 | else g.degree[temp1]++; 59 | it = g.degree.find(temp2); 60 | if(it==g.degree.end()) 61 | { 62 | g.degree[temp2]=1; 63 | } 64 | else g.degree[temp2]++; 65 | } 66 | int Max_len=0; 67 | for(it=g.degree.begin();it!=g.degree.end();it++) 68 | { 69 | int len=0; 70 | dfs(g,(*it).first,len,Max_len,visit); 71 | } 72 | cout< adj[Maxsize]; 8 | set S;//the set of vertices 9 | }; 10 | int main() 11 | { 12 | int T; 13 | cin>>T; 14 | while(T--) 15 | { 16 | Graph g; 17 | int m; 18 | cin>>m; 19 | if(m!=0) 20 | { 21 | int temp1,temp2; 22 | for(int i=0;i>temp1>>temp2; 25 | g.adj[temp1].push_back(temp2); 26 | g.adj[temp2].push_back(temp1); 27 | g.S.insert(temp1); 28 | g.S.insert(temp2); 29 | } 30 | bool visit[Maxsize]; 31 | int distance[Maxsize]; 32 | for(int i=0;idistance[v]+1) 58 | { 59 | distance[g.adj[v][j]]=distance[v]+1; 60 | } 61 | } 62 | } 63 | set::iterator it = g.S.begin(); 64 | int temp; 65 | for(it++;it!=g.S.end();it++) 66 | { 67 | temp=*it; 68 | cout< neighbors; 7 | 8 | Node() {} 9 | 10 | Node(int _val, vector _neighbors) { 11 | val = _val; 12 | neighbors = _neighbors; 13 | } 14 | }; 15 | class Solution { 16 | public: 17 | Node* connectNode(Node *last,Node* node,vector &f) 18 | { 19 | vector::iterator result = f.begin(); 20 | for(;result!=f.end();result++) 21 | { 22 | if((*result)->val==node->val) 23 | { 24 | break; 25 | } 26 | } 27 | if(result!=f.end()) 28 | { 29 | last->neighbors.push_back((*result));//相互之间连边 30 | return NULL; 31 | } 32 | //如果节点不存在 则建立节点 33 | Node *temp = new Node; 34 | f.push_back(temp); 35 | temp->val=node->val; 36 | last->neighbors.push_back(temp);//相互之间连边 37 | return temp; 38 | } 39 | void recursion(Node *new_graph,Node*ori_graph,vector &f) 40 | { 41 | Node *temp; 42 | for(int i=0;i < ori_graph->neighbors.size();i++) 43 | { 44 | if(temp = connectNode(new_graph,ori_graph->neighbors[i],f)) 45 | { 46 | recursion(temp,ori_graph->neighbors[i],f); 47 | } 48 | } 49 | } 50 | Node* cloneGraph(Node* node) 51 | { 52 | if(node == NULL) return NULL; 53 | vector f;//已经建立的节点 54 | Node *new_graph = new Node; // 新的图的第一个节点 55 | 56 | f.push_back(new_graph); 57 | new_graph->val = node->val; 58 | recursion(new_graph,node,f); 59 | return new_graph; 60 | } 61 | }; 62 | int main() 63 | { 64 | //https://github.com/ysyisyourbrother/Leetcode.git 65 | } -------------------------------------------------------------------------------- /数据结构与算法/图/返回无向图度数序列.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/图/返回无向图度数序列.cpp -------------------------------------------------------------------------------- /数据结构与算法/图/邻接矩阵实现图.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/图/邻接矩阵实现图.cpp -------------------------------------------------------------------------------- /数据结构与算法/堆/优先队列的cmp参数使用.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | struct Node 4 | {int adj; 5 | int val; 6 | Node(int x):val(x){} 7 | }; 8 | struct cmp 9 | {bool operator()(Node a,Node b) { return a.val > b.val; } 10 | }; 11 | 12 | int main() 13 | { 14 | priority_queue,cmp>Q; 15 | Node a(4); 16 | Node b(6); 17 | Node c(2); 18 | Q.push(a); 19 | Q.push(b); 20 | Q.push(c); 21 | for(int i=0;i<3;i++) 22 | { 23 | cout<result?currentlen:result; 26 | currentlen=i-find[temp]; 27 | //现在要把重复元素前面的元素find都恢复成-1 28 | for(int j=begin;jresult?currentlen:result; 37 | return result; 38 | } 39 | int main() 40 | { 41 | string a=" "; 42 | cout< merge(vector& intervals) 16 | { 17 | if(intervals.size()==0) return intervals; 18 | sort(intervals.begin(),intervals.end(),cmp); 19 | vector::iterator it=intervals.begin(); 20 | vector::iterator ite=intervals.end(); 21 | while(it=(*(it+1)).start) 24 | { 25 | if((*(it+1)).end<(*it).end) 26 | { 27 | (*(it+1)).start=(*it).start; 28 | (*(it+1)).end=(*it).end; 29 | } 30 | else 31 | { 32 | (*(it+1)).start=(*it).start; 33 | } 34 | it = intervals.erase(it); 35 | ite=intervals.end(); 36 | } 37 | else 38 | { 39 | it++; 40 | } 41 | } 42 | return intervals; 43 | } 44 | }; 45 | int main() 46 | { 47 | 48 | } -------------------------------------------------------------------------------- /数据结构与算法/排序/排序算法/基数排序.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/排序/排序算法/基数排序.cpp -------------------------------------------------------------------------------- /数据结构与算法/排序/排序算法/堆排序.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | #define left(x) 2*x+1 5 | #define right(x) 2*x+2//因为数组下标是从0开始的,所以对应每个非树叶节点x,他的左右节点分别为2x+1 2x+2 6 | void MaxHeap(int *a,int i,int high)//更新某个节点满足最大堆 7 | //a为要排序数组,i为要排序的节点,high为数组要被维护的最大下标 8 | { 9 | int l=left(i); 10 | int r= right(i); 11 | int largest;//三者较大节点下标 12 | int temp; 13 | //找出r l 和 i位置的节点值的最大值 并和i位置交换 14 | if(l<=high && a[l]>a[i]) 15 | largest=l; 16 | else 17 | largest = i; 18 | if(r<=high&&a[r]>a[largest]) 19 | largest=r; 20 | if(largest!=i)//当 最大的值是在位置 i 或者 l和r都不存在时 largest=i,此时不交换,函数返回。 21 | { 22 | temp=a[i]; 23 | a[i]=a[largest]; 24 | a[largest]=temp; 25 | MaxHeap(a,largest,high); 26 | } 27 | 28 | } 29 | void buildMaxHeap(int *a,int length)//将数组建立成一个最大堆 30 | { 31 | for(int i=length/2-1;i>=0;i--) 32 | { 33 | MaxHeap(a,i,length-1); 34 | } 35 | } 36 | void HeapSort(int *a,int length) 37 | { 38 | int temp; 39 | buildMaxHeap(a,length); 40 | for(int i=length-1;i>=1;i--) 41 | { 42 | // for(int i=0;i<5;i++) 43 | // { 44 | // cout< 2 | #include 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | vector sortArray(vector& nums) { 8 | if(nums.size()<=1) return nums; //如果数组的大小小于等于1 直接返回 9 | // 希尔排序 10 | int jump = nums.size()/2; // 定义排序增量间隔 11 | while(jump) // jump每次变为原来的一半 变为0的时候结束 12 | { 13 | for(int i = 0;i & nums, int cur, int jump) 23 | { 24 | // 有增量的直接插入排序 25 | while(cur=0 && nums[x]>tmp) 30 | { 31 | nums[x+jump] = nums[x]; 32 | x-=jump; 33 | } 34 | nums[x+jump] = tmp; 35 | cur+= jump; 36 | } 37 | } 38 | }; 39 | 40 | int main() 41 | { 42 | vector q = {5,2,3,1}; 43 | Solution test; 44 | test.sortArray(q); 45 | for(auto i:q) 46 | cout< sortArray(vector& nums) { 6 | if(nums.size()<=1) return nums; //如果数组的大小小于等于1 直接返回 7 | for(int i =1;i=0 && tmp q = {5,2,3,1}; 24 | Solution test; 25 | test.sortArray(q); 26 | for(auto i:q) 27 | cout< 2 | #include 3 | using namespace std; 4 | int max_key(int *arr,int low,int high) 5 | { 6 | int largest; 7 | largest=low; 8 | for(int i=low+1;i<=high;i++) 9 | { 10 | if(arr[i]>arr[largest]) 11 | largest=i; 12 | } 13 | return largest; 14 | } 15 | void selection_sort(int *arr,int len) 16 | { 17 | for(int position=len-1;position>0;position--) 18 | { 19 | int max = max_key(arr,0,position); 20 | swap(arr[max],arr[position]); 21 | } 22 | } 23 | int main() 24 | { 25 | int a[]={3,5,1,2,0,9,4,5,6,10}; 26 | int len=sizeof(a)/sizeof(int); 27 | selection_sort(a,len); 28 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | //#include "headfile.h" 6 | using namespace std; 7 | bool cmp(int a, int b) 8 | { 9 | string x = std::to_string(a); 10 | string y = std::to_string(b); 11 | return x+y>y+x; 12 | } 13 | std::string largestNumber(vector& nums) 14 | { 15 | sort(nums.begin(), nums.end(), cmp); 16 | /*for (int i = 0; i a; 41 | a.push_back(5); 42 | a.push_back(88); 43 | a.push_back(78); 44 | a.push_back(88); 45 | a.push_back(35); 46 | a.push_back(35); 47 | a.push_back(21); 48 | cout<val; 12 | ListNode* current=head; 13 | while(current->next!=NULL&¤t->next->valval=current->next->val; 16 | current=current->next; 17 | } 18 | current->val=current_val; 19 | 20 | } 21 | ListNode* insertionSortList(ListNode* head) 22 | { 23 | if(head==NULL) return NULL; 24 | ListNode* current=head; 25 | while(current->next!=NULL)//先找到最后一个节点 26 | { 27 | current=current->next; 28 | } 29 | //从最后一个节点开始排序 排到头结点位置停止 30 | while(current!=head) 31 | { 32 | insert_sort(current); 33 | ListNode* temp=current; 34 | current=head; 35 | while(current->next!=temp) 36 | { 37 | current=current->next; 38 | } 39 | } 40 | insert_sort(head); 41 | return head; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /数据结构与算法/查找/Message flood.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/查找/Message flood.cpp -------------------------------------------------------------------------------- /数据结构与算法/查找/【map】两数之和.cpp: -------------------------------------------------------------------------------- 1 | #include "headfile.h" 2 | using namespace std; 3 | vector twoSum(vector& nums, int target) 4 | { 5 | vector result; 6 | map m; 7 | map::iterator it; 8 | for(int i =0;i 2 | #include 3 | #include 4 | using namespace std; 5 | int find_biggest(vector t,int low,int high) 6 | { 7 | int biggest=low; 8 | for(int i=low+1;i<=high;i++) 9 | { 10 | if(t[i]>=t[biggest]) 11 | biggest=i; 12 | } 13 | return biggest; 14 | } 15 | int find_smallest(vector t,int low,int high) 16 | { 17 | int smallest=low; 18 | for(int i=low+1;i<=high;i++) 19 | { 20 | if(t[i]<=t[smallest]) 21 | smallest=i; 22 | } 23 | return smallest; 24 | } 25 | int main() 26 | { 27 | int n,m; 28 | int temp; 29 | cin>>n; 30 | vector arr; 31 | for(int j=0;j>temp; 34 | arr.push_back(temp); 35 | } 36 | 37 | cin>>m; 38 | while(m--) 39 | { 40 | vector t; 41 | for(int j=0;j>temp; 44 | t.push_back(temp); 45 | } 46 | int i; 47 | for(i=0;i nextGreaterElement(vector& findNums, vector& nums) 5 | { 6 | stack sta; 7 | map m; 8 | for(int i=0;i result; 19 | for(int i=0;i a; 28 | vector b; 29 | vector c; 30 | a.push_back(4); 31 | a.push_back(1); 32 | a.push_back(2); 33 | b.push_back(1); 34 | b.push_back(3); 35 | b.push_back(4); 36 | b.push_back(2); 37 | c=nextGreaterElement(a,b); 38 | for(int i=0;i nextGreaterElements(vector& nums) 4 | { 5 | stack sta;//第一个是在extG数组中的下标,第二个是对应位置的值的值 6 | int nextG[10005]={0}; 7 | for(int i=0;i result; 19 | for(int i=0;i a; 28 | vector b; 29 | vector c; 30 | b.push_back(1); 31 | b.push_back(2); 32 | b.push_back(1); 33 | c=nextGreaterElements(b); 34 | for(int i=0;i mysta; 6 | bool ismatch=true; 7 | int i=0; 8 | while(ismatch&&i& pushed, vector& popped) 4 | { 5 | stack a; 6 | int j=0;//poped序列的判断下标 7 | int i=0; 8 | while(j 2 | #include 3 | using namespace std; 4 | typedef int T; 5 | struct treeNode { 6 | T data; 7 | treeNode *left, *right; 8 | 9 | treeNode(T d, treeNode *l=NULL, treeNode *r=NULL):data(d),left(l),right(r){}; 10 | }; 11 | 12 | int width(const treeNode * root) 13 | { 14 | if(root==NULL) 15 | { 16 | return 0; 17 | } 18 | queue q; 19 | int maxwidth=0; 20 | q.push((treeNode *)root); 21 | while(!q.empty()) 22 | { 23 | int count=q.size(); 24 | maxwidth = count > maxwidth ? count : maxwidth; 25 | for(int i=0;ileft!=NULL) 30 | { 31 | q.push(temp->left); 32 | } 33 | if(temp->right!=NULL) 34 | { 35 | q.push(temp->right); 36 | } 37 | } 38 | } 39 | return maxwidth; 40 | } 41 | int main() 42 | { 43 | treeNode a(1); 44 | treeNode b(2); 45 | treeNode c(3); 46 | treeNode d(4); 47 | treeNode e(5); 48 | treeNode f(6); 49 | a.left=&b; 50 | a.right=&e; 51 | b.right=&c; 52 | b.left=&d; 53 | e.left=&f; 54 | cout< 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 12 | }; 13 | void reverse(vector> vv) 14 | { 15 | int i=0,j=vv.size()-1; 16 | for(;i> levelOrderBottom(TreeNode* root) 22 | { 23 | vector> vv; 24 | if(root==NULL) return vv; 25 | queue que; 26 | que.push(root); 27 | while(!que.empty()) 28 | { 29 | vector v; 30 | int size=que.size(); 31 | TreeNode *temp; 32 | for(int i =0;ival); 36 | que.pop(); 37 | if(temp->left!=NULL) que.push(temp->left); 38 | if(temp->right!=NULL) que.push(temp->right); 39 | } 40 | vv.push_back(v); 41 | } 42 | reverse(vv); 43 | return vv; 44 | } 45 | 46 | int main() 47 | { 48 | 49 | } 50 | -------------------------------------------------------------------------------- /数据结构与算法/树/二叉树的高度.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/二叉树的高度.cpp -------------------------------------------------------------------------------- /数据结构与算法/树/前序遍历和中序遍历建立二叉树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/前序遍历和中序遍历建立二叉树.cpp -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/Decoding/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/Decoding/ReadMe.txt -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/Decoding/huffmanCoding inputfile.txt: -------------------------------------------------------------------------------- 1 | If 2 | by Rudyard Kipling 3 | abcdefghidasfasdf 4 | fsadfasasd 5 | dafasd 6 | dasfvsdafas 7 | fasdfasdgasgasdfg 8 | fsdasfs 9 | fsadfasdgasgasd 10 | asdfasfasf 11 | -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/Decoding/huffmanCoding outputfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/Decoding/huffmanCoding outputfile.txt -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/Decoding/huffmanDeCoding inputfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/Decoding/huffmanDeCoding inputfile.txt -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/Decoding/huffmanDeCoding outputfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/Decoding/huffmanDeCoding outputfile.txt -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/Decoding/源.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/Decoding/源.cpp -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/coding/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/coding/ReadMe.txt -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/coding/huffmanCoding inputfile.txt: -------------------------------------------------------------------------------- 1 | If 2 | by Rudyard Kipling 3 | abcdefghidasfasdf 4 | fsadfasasd 5 | dafasd 6 | dasfvsdafas 7 | fasdfasdgasgasdfg 8 | fsdasfs 9 | fsadfasdgasgasd 10 | asdfasfasf 11 | -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/coding/huffmanCoding outputfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/coding/huffmanCoding outputfile.txt -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/coding/源.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/树/哈夫曼编码/coding/源.cpp -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/huffmanCoding inputfile.txt: -------------------------------------------------------------------------------- 1 | If 2 | by Rudyard Kipling 3 | abcdefghidasfasdf 4 | fsadfasasd 5 | dafasd -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/huffmanCoding outputfile.txt: -------------------------------------------------------------------------------- 1 | ^FI{#GBe$#R.|J2PFT /KF6t:p`Y8 -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/huffmanDeCoding inputfile.txt: -------------------------------------------------------------------------------- 1 | ^FI{#GBe$#R.|J2PFT /KF6t:p`Y8 -------------------------------------------------------------------------------- /数据结构与算法/树/哈夫曼编码/huffmanDeCoding outputfile.txt: -------------------------------------------------------------------------------- 1 | If 2 | by Rudyard Kipling 3 | abcdefghidasfasdf 4 | fsadfasasd 5 | dafasd 6 | dasfvsdafas 7 | fasdfasdgasgasdfg 8 | fsdasfs 9 | fsadfasdgasgasd 10 | asdfasfasf 11 | -------------------------------------------------------------------------------- /数据结构与算法/树/完全二叉树的节点个数.cpp: -------------------------------------------------------------------------------- 1 | /*˼·: 2 | 1 �ҵ���ȫ������������ڵ㣬Ҳ����������������� 3 | 2 �ҵ���ȫ������ͷ�ڵ��������е�����ڵ㣬��¼��������� 4 | 3 ������������ȣ�˵��ͷ�ڵ���������һ������������ʹ�ù�ʽ��ó����ټ���ͷ�ڵ㣬Ȼ�����������ʹ�õݹ���� 5 | 4 �����������ȴ�����������ȣ�˵����������һ����ȫ��������ʹ�ù�ʽ��ó����ټ���ͷ�ڵ㣬Ȼ�����������ʹ�õݹ����. 6 | */ 7 | struct TreeNode { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 12 | }; 13 | 14 | class Solution { 15 | public: 16 | int countNodes(TreeNode* root) 17 | { 18 | int count=0; 19 | int ldepth=0,rdepth=0; 20 | if(root==NULL) return 0; 21 | TreeNode* cur; 22 | cur=root->left; 23 | while(cur!=NULL) 24 | { 25 | ldepth++; 26 | cur=cur->left;//����������������� 27 | } 28 | cur=root->right; 29 | while(cur!=NULL) 30 | { 31 | rdepth++; 32 | cur=cur->left;//����������������� 33 | } 34 | if(ldepth==rdepth)//������Ϊ�����������ݹ���������� 35 | { 36 | count = pow(2, ldepth) - 1 + countNodes(root->right) + 1;//����һ���ϸ� 37 | } 38 | else//���������������߶���һ����������� ���ݹ���������� 39 | { 40 | count = pow(2, rdepth) - 1 + countNodes(root->left) + 1; 41 | } 42 | return count; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /数据结构与算法/树/非递归中序遍历.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | template 5 | struct BinaryNode{ 6 | T elem; 7 | BinaryNode *left; 8 | BinaryNode * right; 9 | BinaryNode(T d, BinaryNode *l=NULL, BinaryNode *r=NULL):elem(d),left(l),right(r){}; 10 | }; 11 | template 12 | void inorder_recursive(BinaryNode* root, void (*visit)(T &x)) 13 | { 14 | if(root!=NULL) 15 | { 16 | inorder_recursive(root->left,visit); 17 | visit(root->elem); 18 | inorder_recursive(root->right,visit); 19 | } 20 | } 21 | template 22 | void inorder(BinaryNode* root, void (*visit)(T &x)) 23 | { 24 | stack* > sta; 25 | while(root!=NULL||!sta.empty()) 26 | { 27 | if(root!=NULL) 28 | { 29 | sta.push(root); 30 | root=root->left; 31 | } 32 | else 33 | { 34 | BinaryNode* temp=sta.top(); 35 | sta.pop(); 36 | visit(temp->elem); 37 | root=temp->right; 38 | } 39 | } 40 | } 41 | int main() 42 | { 43 | 44 | } 45 | -------------------------------------------------------------------------------- /数据结构与算法/递归/Fractal.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/递归/Fractal.cpp -------------------------------------------------------------------------------- /数据结构与算法/递归/【全排列】交换字符.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/递归/【全排列】交换字符.cpp -------------------------------------------------------------------------------- /数据结构与算法/递归/【递归】八皇后问题判定.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/递归/【递归】八皇后问题判定.cpp -------------------------------------------------------------------------------- /数据结构与算法/链表/ArrayList, version 2 .cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/数据结构与算法/链表/ArrayList, version 2 .cpp -------------------------------------------------------------------------------- /数据结构与算法/链表/Copy Linked Lists .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | template 4 | struct Node { 5 | Node_entry entry; 6 | Node *next; 7 | Node(); 8 | Node(Node_entry item, Node *add_on = NULL); 9 | }; 10 | 11 | template 12 | Node::Node() 13 | { 14 | next = NULL; 15 | } 16 | 17 | template 18 | Node::Node(Node_entry item, Node *add_on) 19 | { 20 | entry = item; 21 | next = add_on; 22 | } 23 | 24 | 25 | template 26 | Node* copyList( const Node * head ) 27 | { 28 | Node* lst=NULL; 29 | Node* newHead=NULL; 30 | while(head!=NULL) 31 | { 32 | if(lst==NULL) 33 | { 34 | lst=new Node(head->entry,NULL); 35 | newHead=lst; 36 | } 37 | else 38 | { 39 | lst->next=new Node(head->entry,NULL); 40 | lst=lst->next; 41 | } 42 | head=head->next; 43 | } 44 | return newHead; 45 | } 46 | int main() 47 | { 48 | Node* a = new Node(5,NULL); 49 | a->next = new Node(6,NULL); 50 | a->next->next = new Node(7,NULL); 51 | a->next->next->next = new Node(8,NULL); 52 | Node* copy = copyList(a); 53 | while(copy!=NULL) 54 | { 55 | cout<entry<next; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /数据结构与算法/链表/Set Intersection (2) .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | //typedef list set; //don't submit this line 5 | /* 6 | Assume that A and B are sets , which are integers of increasing order, it returns the intersection of A and B . 7 | For example, A = (2,3,5,12), B = (3,5,8,9), then the result returned is (3,5). 8 | */ 9 | set setIntersection(const set &A, const set &B) 10 | { 11 | set::const_iterator irA = A.begin(); 12 | set::const_iterator irB = B.begin(); 13 | set ans; 14 | while(irA!=A.end()&&irB!=B.end()) 15 | { 16 | if(*irA==*irB) 17 | { 18 | ans.push_back(*irA); 19 | irA++; 20 | irB++; 21 | } 22 | else if(*irA>*irB) 23 | { 24 | irB++; 25 | } 26 | else 27 | { 28 | irA++; 29 | } 30 | } 31 | return ans; 32 | } 33 | int main() 34 | { 35 | set A,B; 36 | A.push_back(2); 37 | A.push_back(3); 38 | A.push_back(5); 39 | A.push_back(12); 40 | B.push_back(3); 41 | B.push_back(5); 42 | B.push_back(8); 43 | B.push_back(9); 44 | set ans = setIntersection(A,B); 45 | 46 | set::iterator i; 47 | for(i=ans.begin();i!=ans.end();i++) 48 | { 49 | cout<<*i<<" "; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /数据结构与算法/链表/Set Intersection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cout; 4 | using std::vector; 5 | //typedef vector set; //don't submit this line. 6 | /* 7 | Assume that A and B are sets , which are integers of increasing order, it returns the intersection of A and B . 8 | For example, A = (2,3,5,12), B = (3,5,8,9), then the result returned is (3,5). 9 | */ 10 | set setIntersection(const set &A, const set &B) 11 | { 12 | set Interset; 13 | int i=0,j=0; 14 | while(iB[j]) 23 | { 24 | j++; 25 | } 26 | else 27 | { 28 | i++; 29 | } 30 | } 31 | return Interset; 32 | } 33 | int main() 34 | { 35 | set A; 36 | A.push_back(2); 37 | A.push_back(3); 38 | A.push_back(5); 39 | A.push_back(12); 40 | set B; 41 | B.push_back(3); 42 | B.push_back(5); 43 | B.push_back(8); 44 | B.push_back(9); 45 | set Interset=setIntersection(A,B); 46 | for(int i=0;ival; 16 | l1 = l1->next; 17 | } 18 | if(l2){ 19 | sum += l2->val; 20 | l2 = l2->next; 21 | } 22 | tmp->next = new ListNode(sum%10); 23 | sum /= 10; 24 | tmp = tmp->next; 25 | } 26 | if(sum) 27 | tmp->next = new ListNode(1); 28 | return result->next; 29 | } 30 | -------------------------------------------------------------------------------- /面经/2020 春招 广州字节 飞书后台凉面.md: -------------------------------------------------------------------------------- 1 | ## 字节跳动 广州 后台开发凉面 2 | 3 | 部门:字节跳动广州 效率工程 4 | 5 | ### 一面 6 | 7 | 1. 自我介绍 8 | 2. 看了我项目后开始问gRPC,介绍优缺点,如何传输的(二进制字节流)。如果不好的话你会用什么?我说用web后台来做。接着就问了一些web的传输机制。 9 | 3. http是怎么传输的(文本形式传输) 10 | 4. DNS服务器是什么? 11 | 5. DNS解析的过程 迭代解析,递归解析 12 | 6. 反转网址字符串。例如:www.baidu.com反转成com.baidu.www,要求原地操作。 13 | 7. 觉得字节有什么在这次面试中没展现出来的,可以记录一下,下次面试官会问 14 | 15 | **失败总结:**没有经验,被带着跑,简历上乱写gRPC但没有认真去了解,结果被面试官带到了传输机制上,什么字节流、文本,都没有认真去学,只是知道这么一回事,结果就问一个不会一个。后面又开始问分布式系统的知识,DNS解析过程,都没复习到。感觉简历不能乱写,遇到不会的及时脱坑表达自己不会,要求换个方面问。 -------------------------------------------------------------------------------- /面经/2020春招 字节 广州 面经.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysyisyourbrother/My-Leetcode/88ae4b243442cca0a2a2fff33607e6418ec3e4cc/面经/2020春招 字节 广州 面经.pdf -------------------------------------------------------------------------------- /面经/2020春招 腾讯 深圳后台 pcg 面经.md: -------------------------------------------------------------------------------- 1 | ## 腾讯 深圳后台 面经 2 | 3 | 部门:腾讯PCG QQ看点 部署推荐算法 主要用go语言 4 | 5 | ### 一面 6 | 7 | 时间:2020.3.4 16:00 8 | 9 | 1. 自我介绍 10 | 2. (项目)分布式文件系统介绍重难点,同步的机制如何实现?网络波动的话怎么解决,如果副本服务器宕机怎么解决。 11 | 3. (项目)微信电商小程序,介绍支付的流程模块设计(先创建订单,在对应订单号支付),如何保证安全(session) 12 | 4. 描述快速排序,如何计算时间复杂度(递归树节点) 13 | 5. 深度优先搜索和广度优先搜索,广搜怎么用递归实现(尾递归) 14 | 6. mysql数据库如果每天有1万份数据进来,持续很多年,怎么解决。按照日期分区 15 | 7. http和https介绍,https为什么安全(ssl) 16 | 8. TCP和udp区别 17 | 9. TCP粘包有了解过吗? 18 | 10. 大学上过什么课,拿了多少分,排名多少 19 | 11. 什么时候可以来实习 20 | 21 | ### 二面 22 | 23 | 时间:2020.3.6 15:00 24 | 25 | 1. 自我介绍 26 | 2. (项目)分布式文件系统介绍重难点,同步的机制如何实现?(和一面问了一样的问题) 27 | 3. 1亿条数据取出top1万 考虑到内存不够放的问题,用小顶堆 28 | 4. TCP四次挥手详细介绍 29 | 5. 还有一些小的基础问题,印象不深刻了。 30 | 6. linux 软硬链接区别,类比windows快捷方式 31 | 32 | 8. 算法:https://leetcode-cn.com/problems/merge-sorted-array/ 33 | 34 | 35 | 36 | ### 三面 37 | 38 | 苦苦等待了12天后,终于接到了三面的电话 突击面试 39 | 40 | 2020.3.18 晚上8点 时长30min 41 | 42 | 1. 简单自我介绍 43 | 2. 问分布式文件系统,介绍,同步机制 44 | 3. C++内存对齐(是什么,为什么) 45 | 4. C++的编译过程了解吗?(还没上过编译原理,并且当时就正在上网课) 46 | 5. 大端小端了解吗? 47 | 6. 怎么用计算机算法去判断是否是大端还是小端 48 | 7. linux了解多少指令 49 | 8. linux文件系统是怎么样的 50 | 9. linux软连接硬连接 51 | 10. 四次挥手对应的状态是什么,介绍整个过程 52 | 11. 如何用数据结构描述六度空间问题(用无向图构建,图的最大宽度小于7) 53 | 12. 打篮球打的怎么样 54 | 13. 你目前有什么技术爱好吗? 55 | 56 | -------------------------------------------------------------------------------- /面经/2020春招 腾讯 深圳后台 qq音乐 面经.md: -------------------------------------------------------------------------------- 1 | ### 电话一面 2 | 3 | static各种用法 4 | 5 | const作用 6 | 7 | STL容器,STL内存管理 8 | 9 | vector和list使用场景 10 | 11 | 多态的实现 12 | 13 | 虚函数 14 | 15 | 操作系统项目 16 | 17 | 进程线程区别 18 | 19 | 进程线程通信 20 | 21 | TCP/UDP区别 UDP有什么优点 更快,报头更小 22 | 23 | 描述三次握手,如果第三次丢了怎么办, RST 24 | 25 | HTTP和HTTPS区别 26 | 27 | 输入URL到响应的过程 28 | 29 | socket连接过程 30 | 31 | top k 堆排序和快速排序,复杂度分析 32 | 33 | 数据库索引类型 34 | 35 | hash和b+树 36 | 37 | 为什么用b+树不用平衡二叉树 38 | 39 | 会不会linux 40 | 41 | 42 | 43 | ### 电话二面 44 | 45 | 之前面试有哪些地方做得不好 46 | 47 | 还在面其他公司吗 48 | 49 | 规划,读研吗 50 | 51 | 介绍下你觉得最好的一个项目 52 | 53 | 项目难点 54 | 55 | 通过服务器端,将一个客户端的消息发送到另一个客户端怎么做,用什么数据结构快速的找到对应的套接字,回答map 56 | 57 | map,二叉查找树查找时间复杂度,二者有什么区别 58 | 59 | 顺带说了下select,poll,epoll得区别 60 | 61 | TCP/IP 协议栈分层,每个层作用,为什么要分层 62 | 63 | HTTP状态码 64 | 65 | 登录 token 66 | 67 | 提到使用了base64,base64优点 68 | 69 | 算法题,[只出现一次得数字](https://leetcode-cn.com/problems/single-number/) 70 | 71 | 你最近一年中你觉得哪方面或者哪门课进步比较大 72 | 73 | 你觉得你有什么优势,有什么例子可以体现 74 | 75 | 你觉得做后台开发你有哪些地方还需要加强 76 | 77 | 反问 -------------------------------------------------------------------------------- /面经/2020春招 腾讯TEG.md: -------------------------------------------------------------------------------- 1 | # 腾讯TEG 1面 2 | 3 | 遭遇是真的神奇:pcg那边没挂,简历一直在总监那里,等了12天一直没回复,可能简历锁过期了,直接被TEG给捞了。当时听到是TEG一面心态直接炸裂,还好二面前等到了pcg的总监面,因此没有继续二面。 4 | 5 | 1. 介绍项目经历 6 | 2. 介绍分布式文件系统,整体介绍,问同步方法等 7 | 3. socket相关 8 | 4. 三次握手四次挥手 9 | 5. 操作系统角度分析打开一个文件要经过什么步骤 10 | 6. 内存调度算法(详细介绍clock算法) 11 | 7. linux shell如何删除最近30天的文件 12 | 8. 介绍多态和继承 13 | 9. io复用中select和epoll 14 | 10. 用过什么调试工具,介绍一下GDB 15 | 11. 数据库ACID 16 | 12. 了解什么非关系型数据库(redis) 17 | 13. 介绍一下动态规划的算法(备忘录) 18 | 14. 10亿的数据,存在重复,找出top一万 19 | - 先是说 用堆和set或者哈希来去重(说如果有分布式集群,如何更快) 20 | - 改成多个机器并行排序,然后多路归并(确实有改进) 21 | -------------------------------------------------------------------------------- /面经/2021 春招 广州微信 后台.md: -------------------------------------------------------------------------------- 1 | ## 2021 春招 广州微信 后台 2 | 3 | 部门:广州微信 技术架构组 原来实习的组推荐过来的 4 | 5 | **已拿offer** 6 | 7 | ### 组长面 8 | 9 | 一个小时四道编程题,分析时间复杂度,是否最优解? 10 | 11 | 一、给一个实数x大于0,求y使得y^7+0.5*y=x。 12 | 13 | 输入样例:129 14 | 15 | 输出样例(四舍五入到小数点后第二位小数):2.00 16 | 17 | 18 | 19 | 二、给一棵二叉树,每个结点上有一个不同的整数值val,一个子树上所有节点数值的总和称为字数和,求最大子树和。 20 | 21 | 例如树节点数值如下图,最大子树和为1+4+7=12。 22 | 23 | 3 24 | 25 | / \ 26 | 27 | 1 -5 28 | 29 | / \ 30 | 31 | 4 7 32 | 33 | 34 | 35 | 三、给一个数组a[n],数组大小不超过1e3,数据范围0~1e8,找到三个数(可重复)使得它们的和为指定值T,如果有多个解输出一个即可。 36 | 37 | 输入样例(n a[0] a[1] ... a[n-1] T):4 2 7 3 8 17 38 | 39 | 输出样例:2 7 8 40 | 41 | 42 | 43 | 四、给一个数组a[n],数组大小不超过1e5,数据范围0~1e8,求其异或值最大连续子区间。 44 | 45 | 输入样例:1 4 5 6 46 | 47 | 输出样例(4 ^ 5 ^ 6=7​):7 48 | 49 | 50 | 51 | 1. 自我介绍 52 | 2. C++ string底层原理,如何扩容? 53 | 3. C++相关一些问题 54 | 4. 一些基础题忘了,但问的不多 55 | 5. 项目相关的很多问题 56 | 6. 反问 57 | -------------------------------------------------------------------------------- /面经/2023 秋招 深圳腾讯 微信客户端.md: -------------------------------------------------------------------------------- 1 | ## 腾讯 深圳微信客户端 面经 2 | 3 | 部门:腾讯微信 客户端 C++方向 4 | 5 | ### 一面 6 | 7 | 时间:2023.08.23 8 | 9 | 1. 自我介绍 10 | 11 | 2. 介绍项目 12 | 13 | 3. c++有哪些智能指针,share_ptr是线程安全的吗?有没有不安全的情况? 14 | 15 | 4. 以下定义哪个正确哪个错误? 16 | ```c++ 17 | unique_ptr up1(new int()); 18 | unique_ptr up2 = new int(); 19 | unique_ptr up3(up1); 20 | ``` 21 | 22 | 5. 以下指针分别代表什么意思? 23 | ```c++ 24 | const char *p; 25 | char const *p; 26 | char * const p; 27 | const char * const p; 28 | ``` 29 | 30 | 6. Vector用过没?遇到过什么问题?内存是怎么分配的? 31 | 32 | 7. 以下变量分配在内存的什么区? 33 | ```c++ 34 | int a = 0; //分配在? 35 | char *p1; //分配在? 36 | main() 37 | { 38 | int b; //分配在? 39 | char s[] = "abc"; //分配在? 40 | char *p2; //分配在? 41 | char *p3 = "123456"; //分别分配在? 42 | static int c =0; //分配在? 43 | p1 = (char *)malloc(10); //分配在? 44 | p2 = (char *)malloc(20); //分配在? 45 | strcpy(p1, "123456"); //分配在? 46 | } 47 | ``` 48 | 49 | 8. 编程题,使用你觉得最好的算法: 50 | 有一组数据,5,3,7,1,8,2,9,4,7,2,6,6, 请你用你认为最合适的方式,取出top k个数据,假设k=5 51 | 52 | 53 | -------------------------------------------------------------------------------- /面经/2023 腾讯wxg微信支付 凉面 ZQQ.md: -------------------------------------------------------------------------------- 1 | ## 2023 腾讯微信 广州 c++后台凉面 ZQQ: 2 | 3 | 部门:微信支付 海外支付业务 4 | 5 | ### 一面 6 | 7 | + 首先就是面试官的自我介绍,问了意向实习时间,以及本部门的业务方向,听起来是微信支付的海外支付业务。 8 | 9 | + 然后开始一轮自我介绍,然后根据简历问了一下相关的内容,总结一些你认为这些专业课在整个计算机领域有什么作用,谈谈你的看法。我看你还写了离散数学(大坑,具体概念不记得了),说一说闭包的概念? 10 | 11 | + 然后就是面试官拿了一套腾讯文档出来,一开始是一些基础的c++知识,有看类的大小,变量的大小,类的大小,一个函数(判定输出是多少,有输出?是多少?没输出?有什么问题?),然后就是三道编程题? 12 | + 第一道题字符串查找的题目,给定两个char*的字符串,查找子串的开始的位置多少?(这里有设置一个考点返回值的类型,需要使用const_cast来去掉引用!)(后续复盘,对于这种简单题,还可以在边界条件,输入检测等方面进行考虑!)。 13 | 14 | + 第二道题,是一道设计题,尝试设计一个基于链表的哈希查找?似乎没有太理解面试官的要求,他想要设计kv的哈希,我设计成multiset,哈哈,美其名曰多设计struct即可!挂…. 15 | 16 | + 第三题,手写大小堆算法,用数组模拟即可,三个函数:make_heap, heaplify,heap_insert。第一个函数甚至可以忽略。 17 | 18 | ### 总结 19 | 八股文不问了?一个没问,直接做题....也行吧,“kpi”面了~ 20 | --------------------------------------------------------------------------------