回溯法
背景
模板
result = []
func backtrack(选择列表,路径):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(选择列表,路径)
撤销选择常见例题
集合类

排列类
组合类
练习
最后更新于
result = []
func backtrack(选择列表,路径):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(选择列表,路径)
撤销选择
最后更新于
IList<IList<int>> powerSet = new List<IList<int>>();
IList<int> temp = new List<int>();
int[] nums;
int n;
public IList<IList<int>> Subsets(int[] nums)
{
this.nums = nums;
this.n = nums.Length;
_Backtrack(0);
return powerSet;
}
void _Backtrack(int index)
{
if (index == n)
{
powerSet.Add(new List<int>(temp));
}
else
{
_Backtrack(index + 1);
temp.Add(nums[index]);
_Backtrack(index + 1);
temp.RemoveAt(temp.Count - 1);
}
}IList<IList<int>> powerSet = new List<IList<int>>();
IList<int> temp = new List<int>();
int[] nums;
int n;
public IList<IList<int>> SubsetsWithDup(int[] nums)
{
Array.Sort(nums);
this.nums = nums;
this.n = nums.Length;
Backtrack(0, false);
return powerSet;
}
void Backtrack(int index, bool prevSelected)
{
if (index == n)
{
powerSet.Add(new List<int>(temp));
}
else
{
Backtrack(index + 1, false);
if (index == 0 || nums[index - 1] != nums[index] || prevSelected)
{
temp.Add(nums[index]);
Backtrack(index + 1, true);
temp.RemoveAt(temp.Count - 1);
}
}
}IList<IList<int>> permutations = new List<IList<int>>();
IList<int> temp = new List<int>();
int n;
public IList<IList<int>> Permute(int[] nums)
{
foreach (int num in nums)
{
temp.Add(num);
}
n = nums.Length;
Backtrack(0);
return permutations;
}
void Backtrack(int index)
{
if (index == n)
{
permutations.Add(new List<int>(temp));
}
else
{
for (int i = index; i < n; i++)
{
(temp[index], temp[i]) = (temp[i], temp[index]);
Backtrack(index + 1);
(temp[index], temp[i]) = (temp[i], temp[index]);
}
}
}
IList<IList<int>> permutations = new List<IList<int>>();
IList<int> temp = new List<int>();
int[] nums;
int n;
bool[] visited;
public IList<IList<int>> PermuteUnique(int[] nums)
{
Array.Sort(nums);
this.nums = nums;
this.n = nums.Length;
this.visited = new bool[n];
Backtrack(0);
return permutations;
}
void Backtrack(int index)
{
if (index == n)
{
permutations.Add(new List<int>(temp));
}
else
{
for (int i = 0; i < n; i++)
{
if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]))
{
continue;
}
temp.Add(nums[i]);
visited[i] = true;
Backtrack(index + 1);
temp.RemoveAt(index);
visited[i] = false;
}
}
}IList<IList<int>> combinations = new List<IList<int>>();
IList<int> temp = new List<int>();
int[] candidates;
int n;
public IList<IList<int>> CombinationSum(int[] candidates, int target)
{
Array.Sort(candidates);
this.candidates = candidates;
this.n = candidates.Length;
Backtrack(0, target);
return combinations;
}
void Backtrack(int index, int remain)
{
if (remain == 0)
{
combinations.Add(new List<int>(temp));
}
else
{
for (int i = index; i < n && candidates[i] <= remain; i++)
{
temp.Add(candidates[i]);
Backtrack(i, remain - candidates[i]);
temp.RemoveAt(temp.Count - 1);
}
}
}static string[] lettersArr = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
string digits;
IList<string> combinations;
public IList<string> LetterCombinations(string digits)
{
this.digits = digits;
this.combinations = new List<string>();
if (digits.Length == 0)
{
return combinations;
}
Backtrack(0, new StringBuilder());
return combinations;
}
void Backtrack(int index, StringBuilder combination)
{
if (index == digits.Length)
{
combinations.Add(combination.ToString());
}
else
{
int digit = digits[index] - '0';
string letters = lettersArr[digit];
foreach (char c in letters)
{
combination.Append(c);
Backtrack(index + 1, combination);
combination.Length--;
}
}
}