刷题时间: 2019/04/19 – 2019/04/19
主播:yxc(闫雪灿)
视频链接: https://v.douyu.com/show/mPyq7oJDm4qv1gLY
题号 | 题目 | 链接 |
---|---|---|
17 | Letter Combinations of a Phone Number | https://leetcode.com/problems/letter-combinations-of-a-phone-number/ |
46 | Permutations | https://leetcode.com/problems/permutations/ |
47 | Permutations II | https://leetcode.com/problems/permutations-ii/submissions/ |
78 | Subsets | https://leetcode.com/problems/subsets/ |
90 | Subsets II | https://leetcode.com/problems/subsets-ii/ |
39 | Combination Sum | https://leetcode.com/problems/combination-sum/ |
15 | 3Sum | https://leetcode.com/problems/3sum/ |
22 | Generate Parentheses | https://leetcode.com/problems/generate-parentheses/ |
437 | Path Sum III | https://leetcode.com/problems/path-sum-iii/ |
解题心得
No.17 Letter Combinations of a Phone Number (AC)
- dfs来做
- 唯一需要注意的是,记录每一个答案的path在代码中如何传递。若用全局变量,则会存在字符叠加的情况,即使在把path加到ans那一步删掉最后一个字符,也会存在最有一个字符前的字符不能删掉而产生重复的情况。若在递归前更新path为path += char[i][j],那么写完递归dfs后应马上删掉这个字符,path = path.erase(path.begin() + path.size() - 1)。为了简化,可以不更新path的值,直接在dfs中把当前字母加到path中。
- 为简化代码,用一个二维字符数组存储数字与字母的对应关系。用vector数组,直接{“”,“”,…}有问题。
No.46 Permutations (AC)
- DFS来做
- 每次将后面没有被枚举的位置依次和当前队列第一个元素交换,然后dfs。需要注意的是,dfs结束之后还原原状。(Method1)
- 另一种相似的思路,记录每个元素是否被访问,若还没有被访问过,则枚举依次加入后dfs的情况。(Method2)
No.47 Permutations II (AC)
- DFS来做
- 用上一题中的Method1来做。需要注意的是排除重复的答案。 可以用set数据结构。
set数据结构
特点:所有元素都会根据元素的键值自动排序,不允许两个元素有相同的键值,可用于去重。
begin()--返回指向第一个元素的迭代器
end()--返回指向最后一个元素的迭代器
empty()--判空
clear()--清空
size()--集合中元素数目
insert()--插入元素
erase()--删除元素
find()--返回一个指向被查找到元素的迭代器
set中的元素不能直接用s[i] 访问,正确访问方法是:
set<vector<int> > s;
set<vector<int> >::iterator it;
for (it = s.begin(); it != s.end(); it++){
vector<int> tmp = *it;
}
No.78 Subsets (AC)
- 一次枚举答案长度为0~len长度的情况
- 为了避免重复答案,在dfs时,记录当前path最后一个元素的索引,保证path中的元素的索引是单调递增的。
No.90 Subsets II (AC)
- 和上一题方法相似,不同之处在于本题中给定元素含有重复数字,所以用set数据结构去重。为了避免[1,4,4,4],[4,1,4,4]这一类重复,在求所有组合之前把给定数组排序。
- 在做组合问题时,都可以先做这一步,排序!
No.39 Combination Sum (AC)
- 和上一题类似,target = 0时输出方案数。
- 用set数据结构去重
No.15 3Sum (TLE–> AC)
- 这类求若干个数的和为固定值的题目,可以直接用递归或者dfs来做。不过这类方法的问题是,时间复杂度是组成某个值得数的个数的指数级别。在本问题中,是三个数组成0,因此上面两种算法得到的时间复杂度为O(n^3),提交TLE。
- 解决方法是,一重循环,在循环过程中,用双指针找到另外两个数,和是当前循环数的相反数即可,可以将时间复杂度将为O(n^2)。
- 实现中还有几个细节问题要注意,一是要用set数据结构去重;二是,在用双指针找剩下的两个数的时候,找到一个合适的组合之后,可以将左边的指针右移,寻找下一组合适的组合,不能直接跳出循环,直接跳出会导致结构不全;三是在寻找下一组合适的组合时,上一组被压入栈的元素需要弹出,不能结果中将会有5个数,甚至更多。
No.22 Generate Parentheses (AC)
- dfs来做
- 把path作为函数参数传递;把’('当做 +1, ‘)’ 当做 -1, 当枚举完所有个数,如果和为0,则是符合要求的组合。
- 在枚举时需要注意,若当前sum>0,则可以枚举’(’ 或 ‘)’,若sum == 0,则只能枚举’(’。按照这规则是不会出现sum < 0的情况的,sum<0直接返回即可。
No.437 Path Sum III (AC)
- 题意:在二叉树中求路径和,不要求从根结点开始,到尾结点结束。
- 双递归实现
- 注意边界为空条件的判断。使用
root->val / root->left / root->right
时要保证root结点不为空。