前言
从力扣100题开始的算法总结,决定真正走科班的代码之路后,果然还是得彻底从头开始总结一些算法代码了,感觉会是一个长期的总结过程,而且还要保持长期热情,只能加油吧。之前技能点全点在做游戏上了,但如果真的决定要改变世界,那就不能止步不前了。
这个总结目前来说还比较简单片面,后续可能考虑针对各个算法进行单一深入应用总结。

哈希
这一部分其实主要是利用哈希表来辅助解决问题。
可能困难比较大的是记住哈希表的使用方式(呃呃这就是记性差的坏处了)
记住之后很多问题在考虑到查找、拼接就可以直接从哈希表入手了:
unordered_map<string, vector<string>> groups; for(auto it = groups.begin(); it != groups.end(); it++) { ans.emplace_back(it->second); }
unordered_set<int> st(nums.begin(), nums.end()); st.contains(x - 1);
|
经典题目链接:
49. 字母异位词分组 - 力扣(LeetCode)
128. 最长连续序列 - 力扣(LeetCode)
双指针
双指针题目比较灵活,可以有以下两类(目前):
- 指针同时出发,主要挪动一个指针,满足特定条件再挪动另一个指针
- 指针同时出发,但是位于数列两端,进行比较选择挪动的指针
代表性题目分别有:
283. 移动零 - 力扣(LeetCode)
42. 接雨水 - 力扣(LeetCode)
滑动窗口
先附上比较玄妙的一道题:
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)
这个的话比较字面意思,有点像双指针,主要通过动态调节窗口大小,来满足特定条件
主要操作是拓展窗口、缩减窗口、比较、选择。
然后可能会和子串在一起。
子串
普通数组
矩阵
链表
二叉树
图论
回溯
主要是有一个标准的板子
在此记录一下(其实感觉不是很难)
题目出处:46. 全排列 - 力扣(LeetCode)
class Solution { private: vector<vector<int>> res; vector<int> path; public: void backtracking(vector<int>& nums, vector<bool>& used) { if (path.size() == nums.size()) { res.push_back(path); return; }
for (int i = 0; i < nums.size(); i++) { if (used[i] == true) continue;
used[i] = true; path.push_back(nums[i]); backtracking(nums, used); path.pop_back(); used[i] = false; } }
vector<vector<int>> permute(vector<int>& nums) { vector<bool> used(nums.size(), false); backtracking(nums, used); return res; } };
|
还有感觉时不时可以回忆一下n皇后:51. N 皇后 - 力扣(LeetCode)
把**行(row)**视为回溯推进的路标!
感觉重要的就是路标的标定和查找。
二分查找
感觉是因为自己有一个很笨笨的方法,导致写的每次逻辑都非常不通畅。
因此在此记录下两者区别:
题目出处:153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)
官方题解:
class Solution { public: int findMin(vector<int>& nums) { int low = 0; int high = nums.size() - 1; while (low < high) { int pivot = low + (high - low) / 2; if (nums[pivot] < nums[high]) { high = pivot; } else { low = pivot + 1; } } return nums[low]; } };
作者:力扣官方题解 链接:https: 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|
我的铸币理解:
class Solution { public: int findMin(vector<int>& nums) { if(nums.size() == 1) return nums[0]; return find(0,nums.size()-1,nums); }
int find(int left,int right,vector<int> nums) { int mid = (left + right)/2; if(left == right-1) { return nums[right] > nums[left] ? nums[left] : nums[right]; } else if(nums[mid]<nums[left]) { return find(left,mid,nums); } else if(nums[mid]>nums[right]) { return find(mid,right,nums); } else { return nums[left]; } } };
|
栈
堆
贪心算法
嘶……
大部分贪心都被我用dp过去了……
不过这道倒是dp没想出来:
45. 跳跃游戏 II - 力扣(LeetCode)
动态规划
感觉没有想象中的那么恐怖,其实就是要找到一条可以表示所有情况的通式。
接着找到他的初状态就可以了。
最好是要常备草稿纸!
多维动态规划
技巧