回溯算法学习笔记
回溯算法
基本思路
解决一个回溯问题,实际上就是一个决策树的遍历过程。只需要思考 3 个问题:
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。
伪代码实现回溯算法框架:
Backtrack(选择列表,路径):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
Backtrack(选择列表,路径)
撤销选择回到上一步
相关经典问题
一、全排列问题
c#解法
IList<LinkedList<int>> res = new List<LinkedList<int>>();
IList<LinkedList<int>> Permute(IList<int> nums)
{
LinkedList<int> track = new LinkedList<int>();
Backtrack(nums, track);
return res;
}
public void Backtrack(IList<int> nums, LinkedList<int> track)
{
if (track.Count == nums.Count)
{
res.Add(new LinkedList<int>(track));
return;
}
for (int i = 0; i < nums.Count; i++)
{
if (track.Contains(nums[i]))
{
continue;
}
track.AddLast(nums[i]);
Backtrack(nums, track);
track.RemoveLast();
}
}
二、N 皇后问题
c#解法
public IList<IList<string>> SolveNQueens(int n)
{
IList<IList<string>> res = new List<IList<string>>();
IList<string> board = new List<string>(n);
char[] tempchar = new char[n];
for (int i = 0; i < n; i++)
{
tempchar[i] = '.';
}
for (int j = 0; j < n; j++)
{
board.Add(new string(tempchar));
}
backtrack(board, 0, res);
return res;
}
public void backtrack(IList<string> board, int row, IList<IList<string>> res)
{
if (row == board.Count)
{
res.Add(new List<string>(board));
return;
}
int n = board.Count;
for (int col = 0; col < n; col++)
{
if (!isValid(board, row, col))
{
continue;
}
string temp = board[row];
char[] chars = temp.ToCharArray();
chars[col] = 'Q';
board[row] = new string(chars);
backtrack(board, row + 1, res);
board[row] = temp;
}
}
public bool isValid(IList<string> board, int row, int col)
{
int n = board.Count;
for (int i = 0; i < n; i++)
{
if (board[i][col] == 'Q')
return false;
}
for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++)
{
if (board[i][j] == 'Q')
return false;
}
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)
{
if (board[i][j] == 'Q')
return false;
}
return true;
}