zoukankan      html  css  js  c++  java
  • 回溯算法学习笔记

    回溯算法

    基本思路

    解决一个回溯问题,实际上就是一个决策树的遍历过程。只需要思考 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;
    }
    
  • 相关阅读:
    C#dll中无法找到c++dll中函数的入口
    C#委托及事件处理机制浅析
    lib和dll的例子
    C#中自定义消息,与MFc对比
    MFC消息响应机制 q
    MFC中消息响应机制
    C# 消息处理机制及自定义过滤方式
    c++中__declspec用法总结
    C++中使用接口
    C# 位域[flags] 转
  • 原文地址:https://www.cnblogs.com/muphalem/p/13617951.html
Copyright © 2011-2022 走看看