1.两数之和等于target。用哈希表。
15.三数之和等于target。
19.删除链表的倒数第N个节点。设置一个dummy节点指向头结点,快指针移动N个节点,然后快慢指针一同移动。
20.三种括号是否正确匹配。用栈。
31.求全排列的下一个数。从右到左找到第一个上升的位置k:k+1,从右到左找到比元素k大的j,交换元素jk,逆序k之后的数。
42.直方图接雨水。用双指针从两边往中间遍历,由于短板效应,哪边小移动哪边。
45.问55题跳跃的最少次数。在55题的基础上,用一个next变量保存下一次最多跳到哪里,遍历到next时用cur更新next。
55.给定一个数组,数字为在该位置跳的最远距离,问能否跳到最后。用一个变量cur存储当前能跳的最远距离。
56.合并区间。将区间按照左边界排序,当后一个区间的左边界小于前一个区间的右边界时,更新后者并将后一个区间删掉。
71.Unix化简文件夹路径。用vector模拟栈的操作,stringstream分割字符串。
72.编辑距离。
76.最短覆盖子串长度。用两个map存需要的字母个数和当前窗口的字母个数,用双指针遍历窗口。
84.直方图中的最大矩形。用栈维护单调递增序列,遇到小的就把前面更大的出栈结算,结尾添加0可以减少代码量。
85.最大子矩阵。每一行向上的直方图中调用84题函数计算最大矩阵。
94.树的中序遍历。非递归实现,先不断遍历左子树并入栈,然后栈顶出栈打印,转到右子树后继续之前操作。=>144、145
121.股票只允许一次交易。遍历时不断更新最小值,以及最大利润。
122.股票不限交易次数。遍历时遇到上升值则将差值加入利润。
123.股票允许最多两次交易。用四个变量分别记录第一次或第二次买入或卖出后的最优值,遍历更新。=>188、309、714
144.树的先序遍历。非递归实现,根节点先入栈,出栈时先将右节点入栈,再将左节点入栈。
145.树的后序遍历。非递归实现,将先序遍历的左右节点互换,遍历结果逆序。
149.给定二维平面上一些点,求最多的点数,满足这些点在同一条直线上。TODO
150.逆波兰式求结果。用栈。
155.最小栈。入栈时有极小值(相同的也算)就入最小栈,出栈时遇到相同值最小栈也出栈。
162.寻找峰值。二分法查看中间元素是否为峰值,若不是则取两边较高的区间。
173.二叉查找树的下一个最小数。逆中序遍历二叉树入栈。
188.股票允许最多k次交易。和123题思路一样,改用2*k个变量保存最优值。
204.统计小于n的素数有多少。用素数筛,遍历i时,从i*i开始每隔i置为false。
208.前缀树。用next[26]数组保存下一层节点指针。
224.有括号的加减计算器。TODO
226.翻转二叉树。递归,先用temp保存左子树的根,然后令左子树等于右子树的翻转,右子树等于temp的翻转。
300.最长上升子序列。用数组保存长度为i的子序列最小结尾,通过二分的方法找到不小于当前数的位置,更新这个数组。=>334
309.有冷却时间的股票交易。用三个变量依次记录当天买入、卖出、冷却的最优收益,遍历更新。
334.上升三元组。利用最长上升子序列的做法,用两个变量保存数组的前两个数,当数组长度大于三返回正确。
406.身高重建队列。将数据从高到底排序,因为序号代表排在之前更高的人数,遍历数据依据序号插入结果序列对应位置。
543.求二叉树两个相距最远节点。递归遍历节点计算深度,分别计算左子树与右子树的最大深度,他们的和的最大值即为所求。
560.和为k的连续子序列数目。用前缀和处理,用哈希表记录前缀和出现次数。
712.TODO
714.股票不限交易次数,每次交易支付费用。用两个变量维护当前买入和卖出的最优值,为防止int溢出在买入阶段扣除费用。
862.和至少为k的最短连续子数组。双端队列维护前缀和递增,入队前差值大于k则队首出队,并将队尾比它大的值出队。
901.股票跨度,当天股价大于等于之前股价的连续天数。维护一个单调递减的栈,栈中存放pair<股价,股票跨度>。
1027.TODO
1178.TODO
1184.求环上两点的最短距离。min(前缀和,总长减去前缀和)。
1185.求某天是星期几。确定某个初始日期是星期几,不断累积年月日对应的天数。
1186.求可删除一个元素的最大连续子序列和。53题的变种,分别向左和向右遍历存储前缀和,然后遍历删除的元素求和。
1187.用数组2的元素替换使得数组1严格递增。TODO
1192.给一个无向连通图,求所有割边。TODO
1339.将二叉树割开,求和的乘积最大值。两次递归求解所有元素的和以及乘积最大值。
1340.跳跃游戏V。在距离d范围内选择可以跳跃的点递归求解可以跳跃的最大次数。
字节跳动最近手撕算法题
甲乙两人从左到右取数字,规定每次取1~M个数字,两人都会最大化自己的得分,问先手得分多少?hard dp
中序遍历非递归实现
class Solution {
public:
vector inorderTraversal(TreeNode* root) {
vector res;
stack st;
while(!st.empty()||root!=NULL){
while(root!=NULL){
st.push(root);
root=root->left;
}
root=st.top();
st.pop();
res.push_back(root->val);
root=root->right;
}
return res;
}
};
class Solution {
public:
vector preorderTraversal(TreeNode* root) {
stack st;
vector res;
if(root==NULL)return res;
st.push(root);
while(!st.empty()){
root=st.top();
st.pop();
res.push_back(root->val);
if(root->right)st.push(root->right);
if(root->left)st.push(root->left);
}
return res;
}
};
class Solution {
public:
vector postorderTraversal(TreeNode* root) {
vector res;
if(root==NULL)return res;
stack st;
st.push(root);
while(!st.empty()){
root=st.top();
st.pop();
res.push_back(root->val);
if(root->left)st.push(root->left);
if(root->right)st.push(root->right);
}
reverse(res.begin(),res.end());
return res;
}
};
洗牌算法,证明随机性
数字序列重排找到比他大的下一个
class Solution {
public:
void nextPermutation(vector& nums) {
int n=nums.size();
int k=n-2,j=n-1;
while(k>=0 && nums[k]>=nums[k+1])k--;
if(k<0){
reverse(nums.begin(),nums.end());
}else{
while(j>k && nums[j]<=nums[k])j--;
swap(nums[j],nums[k]);
reverse(nums.begin()+k+1,nums.end());
}
}
};
五子棋+1,-1,0判断黑棋赢了没
无序数组找中位数(partition)
扑克牌的移动,每次从手上牌堆顶先拿一张牌放桌子上,然后把手上牌堆顶的牌放到最底部