0%

此处和 40.组合总和II 较为相似,在集合中存在重复的元素,在结果中需要防止重复选取问题,也就是在回溯时,对于当前元素 nums[cur] 需要跳过后面全部与他值相同的元素。(依旧是存在两种处理方式,一个是使用for循环进行跳过,两外则是对重复元素进行统计,在递归时分别处理选取 0-n 个元素的情形。)

阅读全文 »

1.1 DFS实现

在本题中使用DFS实现存在一定的难度,但是也不失为一种实现方式,基本思想为:采用根右左的方式进行深度优先搜索,那么在第一次到达新的一层时,访问的节点就是二叉树每层的最右侧节点。那么在DFS中需要做的是就是判断,何时时第一次当前层的。

阅读全文 »

枚举元素是否选取

基本思想为,使用递归函数创建一个子集,让子集成为递归树中的叶子节点,那么在到达叶子节点后,就能够实现选取。在创建子集时序列中的元素仅有两种状态,选取或不选取:

  1. 选取当前元素 nums[cur] ,然后 cur+1 向下递归,那么就能够找到包含当前元素的全部子集
  2. 不选取当前 nums[cur] ,然后 cur+1 向下递归,那么就能够找到不包含当前元素的全部子集
  3. 递归结束的条件: cur=nums.size() 此时将会到达叶节点
阅读全文 »

本题实际上就是向一个数字字符串中加入三个 . 使得最终的结果满足IP地址的定义。对于IP地址的要求为 0-255,并且要求不包含前导的0元素。此处的处理方式和 131.分割回文串 类似,也可以生成相应的IP判断二维数组,但是相应的子串是否符合IP地址的定义并不需要使用动态规划法进行判断。

创建是否满足IP的数组将导致空间复杂度的上升,因此此处也可以采取生成相应的子串后再判断的方式。

基本思路:首先,将 s[cur] 处的的子串作为IP地址中的一段,并判断是否符合规范,符合规范,tmp.push_back(s.substr(cur,1)) ,开始递归 cur+1 ,递归返回后, tmp.pop_back 完成回溯。然后选取 s[cur:cur+1] 处的作为子串,判断是否为IP

阅读全文 »

暴力穷举的回溯

对于子串的划分,初始仅选取 cur 处的元素作为子串 str ,判断生成的子串是否是回文,若是回文则将子串加入到 tmp 数组中,cur+1 开始递归,在递归返回后,将 tmp 中的值pop完成回溯,在下一步循环中将 s[i] 加入到 str 中作为新的字串,再做判断和递归回溯。

阅读全文 »

相较于 39.组合总和,本题的主要区别在于, candidates 数组中的元素是重复的,并且存在特殊情况: 对于 [10,1,2,7,6,1,5] 从中组合8,存在特殊的重复问题,对于两个编号1都能够组成 [1,7] 但是在结果中将会被判定为重复。

此处修改的重点在于,选取 cur 并且完成递归后回溯时,那么在后序的递归需要跳过相同的元素。在总体的for循环内添加一个新的for循环,让其能够跳过相同元素,并且此处还需要着重判断数组越界问题:

阅读全文 »

相较于 216.组合总和III 本题的重要区别在于:要求从参数序列中进行元素的选取,元素允许重复选取,对选取元素的数量没有要求。

那么依旧是回溯的思想进行,为了实现元素的重复选取,在for循环中选取了当前元素 candidate[cur] 后,进入递归时传递的参数 cur 应当不变,也就保证了在下一层递归中依旧可以选取元素 candidate[cur] ,并且为了防止出现 [2,2,3][2,3,2] 的情形,每次都从 cur 开始选取。

阅读全文 »

此处的要求就是穷举,那么对于每一个数字中的每一个字母都需要选取一次,基本思想就是选取当前字母递归,在递归返回后,回溯选取(不选当前字母),进入到下一次递归中。

阅读全文 »