题目做后还是要做一下总结,才能确切的知道自己通过做题收获了什么。
之前我一直享受刷题的快感,懒于及时做整理、总结,拖到了现在,刷了200题才打算开始。
这200题中有水题,有自己冥思苦想才解出的题,也有苦想之后做不出来然后看答案的题,也有一看题就知道自己不会做然后直接看答案的题。
另外,给想要刷Leetcode的朋友一点建议,做题前不用太在意题目标注的难度,主要看题目里的点赞次数和反对次数,我一般选择高赞低反对的题,发现这些题都是比较有料的。
979. Distribute Coins in Binary Tree
class Solution {
public:
//节点的coin为n,那它势必要移走或者移入n-1次
//自底向上分配
int dfs(TreeNode* root,int& ans)
{
if(root==NULL)
return 0;
int left = dfs(root->left,ans),right = dfs(root->right,ans);
ans += abs(left)+abs(right);
return root->val+left+right-1; //自底向上分配,每个节点只与其左右子节点有关
}
int distributeCoins(TreeNode* root) {
int ans = 0;
dfs(root,ans);
return ans;
}
};
▲对于一些给定数组作为参数的题目,如果要求解的内容与元素在数组中对应的位置无关,那么可以尝试对数组进行排序寻求思路。
▲如何将二叉树化成图:先过一遍DFS,记录节点对应的父结点(可以采用unordered_map),之后在遍历所有节点的时候对于每一个节点就可以同时遍历它的子结点和父结点,这比较常用于BFS,按层或者按距离一步步增加展开搜索。
974. Subarray Sums Divisible by K
由该题,引出一种思路:有的题目跟数学联系紧密,可以先观察问题中的数学联系,结合编程和数学知识解题
该题中:(sum%K+K)%K:防止了余数为负数,不可作为数组下标的情况出现;
(mod[i]*(mod[i]-1)/2): 余数相同的子序列的和相减,得到可以被K整除的子序列,所以记录余数为0-K的子序列的个数,求组合数
class Solution {
public:
int subarraysDivByK(vector<int>& A, int K) {
int n = A.size();
vector<int> mod(K,0); // count
int ans = 0,sum = 0;
for(int i=0;i<n;++i)
sum+=A[i],mod[(sum%K+K)%K]++; //avoid negative remainder
for(int i=0;i<K;++i)
ans+=(mod[i]*(mod[i]-1)/2); //combination
ans += mod[0]; // all sum which module K result 0 can be a subarray separately
return ans;
}
};
973. K Closest Points to Origin 求前K个靠近原点(0,0)的点
这道题只是求每个点与原点的距离然后做个排序,取较小的前K个,很简单。但通过看别人的解法,学到了**STL中一个划分排序的函数: