-
93复原IP地址
- 代码随想录 (programmercarl.com)
-
第一印象
- 这是一道切割的题目,切割点就在
.上,在判断是否是有效数字时需要仔细讨论
-
讲解观后感
- 本题除了要有
idx记录分割位置,还要有pointnum记录逗点的数量,终止条件也是达到3个逗点时判断。或者用path记录分段数,到达4段后终止。
-
解题代码
-
var (
path []string
res []string
)
func restoreIpAddresses(s string) []string {
path, res = make([]string, 0, len(s)), make([]string, 0)
dfs(s, 0)
return res
}
func dfs(s string, start int) {
if len(path) == 4 {
if start == len(s) {
str := strings.Join(path, ".")
res = append(res, str)
}
return
}
for i := start; i < len(s); i++ {
if i != start && s[start] == '0' {
break
}
str := s[start : i+1]
num, _ := strconv.Atoi(str)
if num >= 0 && num <= 255 {
path = append(path, str)
dfs(s, i+1)
path = path[:len(path) - 1]
} else {
break
}
}
}
-
78子集
- 代码随想录 (programmercarl.com)
-
第一印象
- 这题和组合十分相似,不限制组合数量并且不能重复的就是子集。用
path记录子集,因为元素不会重复,所以直接idx+1向下添加即可。
- 不要忘了添加空集。
-
解题代码
-
func subsets(nums []int) [][]int {
ans := [][]int{}
path := []int{}
kong := []int{}
ans = append(ans, kong)
if len(nums) == 0 {
return ans
}
var backtrac func(nums []int, idx int)
backtrac = func(nums []int, idx int) {
for i:=idx;i<len(nums);i++ {
path = append(path, nums[i])
tmp := make([]int, len(path))
copy(tmp, path)
ans = append(ans, tmp)
backtrac(nums, i+1)
path = path[:len(path)-1]
}
return
}
backtrac(nums, 0)
return ans
}
-
90子集II
- 代码随想录 (programmercarl.com)
-
第一印象
- 78子集题的升级版,当集合内有重复元素的时候,如何进行去重就是需要着重处理的对象。第一想法是使用排序后类似used数组的标记方式。
-
讲解观后感
- 也可以直接使用
i!=idx&&nums[i]==nums[i-1]的方式来去重
-
解题代码
- 不使用used
-
func subsetsWithDup(nums []int) [][]int {
ans := [][]int{}
path := []int{}
kong := []int{}
ans = append(ans, kong)
if len(nums) == 0 {
return ans
}
sort.Ints(nums)
var backtrac func(nums []int, idx int)
backtrac = func(nums []int, idx int) {
for i:=idx;i<len(nums);i++ {
if i!=idx&&nums[i]==nums[i-1] {
continue
}
path = append(path, nums[i])
tmp := make([]int, len(path))
copy(tmp, path)
ans = append(ans, tmp)
backtrac(nums, i+1)
path = path[:len(path)-1]
}
return
}
backtrac(nums, 0)
return ans
}
- 使用used(C++)
-
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {
result.push_back(path);
for (int i = startIndex; i < nums.size(); i++) {
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
path.push_back(nums[i]);
used[i] = true;
backtracking(nums, i + 1, used);
used[i] = false;
path.pop_back();
}
}
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
result.clear();
path.clear();
vector<bool> used(nums.size(), false);
sort(nums.begin(), nums.end());
backtracking(nums, 0, used);
return result;
}
};