刷题笔记2022.3.3
- 给定两个整数n和k,返回范围 [1, n] 中所有可能的 k 个数的组合。你可以按任何顺序返回答案。标签是回溯。我印象中的回溯是八皇后问题,但我并不会做。
方法:递归实现组合型枚举
n个元素选 k个,在dfs的时候需要多传入一个参数 k,即 dfs(cur,n,k)。在每次进入这个dfs 函数时,我们都去判断当前 temp 的长度是否为 k,如果为 k,就把temp 加入答案并直接返回,即:
解决⼀个回溯问题,实际上就是⼀个决策树的遍历过程。
也就是Dfs遍历决策树
我们只要在递归之前做出选择,在递归之后撤销刚才的选择,就能正确得到
每个节点的选择列表和路径。
其核⼼就是 for 循环⾥⾯的递归,在递归调⽤之前「做选择」,在递归调⽤
之后「撤销选择」,特别简单。
因为穷举整棵决策树是⽆法避免的。这也是回溯算法的⼀
个特点,不像动态规划存在重叠⼦问题可以优化,回溯算法就是纯暴⼒穷
举,复杂度⼀般都很⾼。
- 全排列。排列和组合是很不一样的,排列比组合考虑的要多一点。
只需在nums里面操作,[8, 9 | 2, 5, 10]->[8, 9, 10 | 2, 5]
for循环,从cur到最后,cur里面有递归。
- 字母大小写全排列。这里几个字母的顺序不变,但是大小写的顺序随意。
要判断是否是字母->大写还是小写->大小写的顺序
A:65,Z:90,a:97,z:122,数字48-57
我的思路:在便利的过程中随机给大小写,但是得遍历多少遍?太多了。多个空间记录就好了
在遍历的时候进行:
如果下一个字符 c 是字母,将当前已遍历过的字符串全排列复制两份,在第一份的每个字符串末尾添加 lowercase(c),在第二份的每个字符串末尾添加 uppercase(c)。
如果下一个字符 c 是数字,将 c 直接添加到每个字符串的末尾。
这里在面临数字选择的时候,就相当于不用回退了,同时有很多支线。
s不断地被改变,一次次放进答案里。
- 二叉树的层序遍历。跟我想的差不多,就是用数组和队列。值得注意的是双层vector可以用单层vector填充。考虑好循环的每一层负责干嘛。每次for循环处理有左右孩子的入队问题,每循环一次就把队头数值入容器并出队。
每次while循环表示更新一次队列,为完成一层。
- 二叉树的最大深度。直觉是用递归。左子树和右子树的最大深度又用一样的方式算。最后别忘了加上第一层。
- 判断二叉树是否沿轴对称。
这可怎么弄。通过「同步移动」两个指针的方法来遍历这棵树,pp 指针和 qq 指针一开始都指向这棵树的根,随后 pp 右移时,qq 左移,pp 左移时,qq 右移。每次检查当前 pp 和 qq 节点的值是否相等,如果相等再判断左右子树是否对称。