回溯算法学习笔记

回溯算法

基本思路

解决一个回溯问题,实际上就是一个决策树的遍历过程。只需要思考 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;
}
posted @ 2020-09-05 13:32  Muphalem  阅读(125)  评论(0编辑  收藏  举报
/* 看板娘 */