【刷题篇】回溯算法(深度优先搜索(一))

文章目录

  • 无重复字符串的排列组合
  • 员工的重要性
  • 图像渲染
  • 被围绕的区域

无重复字符串的排列组合

无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。

【刷题篇】回溯算法(深度优先搜索(一))_第1张图片

class Solution {
public:
    void DFS(string &s,vector<string>&dfs,int i)
    {
        if(i==s.size())
            dfs.push_back(s);
        else
        {
            //注意 j 的下标从 i 开始,因为原排列也是一种排列
            for (int j = i; j < s.length(); ++ j)
            {
                swap(s[i], s[j]);       //交换字母
                DFS(s, dfs, i + 1);
                swap(s[i], s[j]);       //还原
            }
        }
    }
    vector<string> permutation(string S) {
        vector<string> res;
        DFS( S,res, 0);
        return res;
    }
};

员工的重要性

给定一个保存员工信息的数据结构,它包含了员工唯一的 id,重要度和直系下属的id比如,员工1是员工2的领导,员工2 是员工3 的领导。他们相应的重要度为 15,10,5。那么员工1的数据结构是[1,15,[2]],员工2的 数据结构是 2, 10,[3]],员工3 的数据结构是[3,5,。注意虽然员工3 也是员工1的一个下属,但是由于并不是直系下属,因此没有体现在员工1的数据结构中。
现在输入一个公司的所有员工信息,以及单个员工id,返回这个员工和他所有下属的重要度之和

【刷题篇】回溯算法(深度优先搜索(一))_第2张图片

class Solution {
public:

    int DFS(vector<Employee*>& employees,int id)
    {
        int sum=0;
        //先遍历数组employees[],
        for(auto e : employees)
        { 
            //确定是哪个id
            if(e->id==id)
            {
                //将importance的值先赋值给sum最后都会递归返回
                sum=e->importance;
                //这里遍历subordinates依次遍历
                for (auto n : e->subordinates) 
                {
                    sum += DFS(employees, n);
                }
            }
        }
        return sum;
    }

    int getImportance(vector<Employee*> employees, int id) {
        return DFS(employees,id);
    }
};

图像渲染

有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。
你也被给予三个整数 sr , sc 和 newColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。
为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor 。
最后返回 经过上色渲染后的图像 。
【刷题篇】回溯算法(深度优先搜索(一))_第3张图片

class Solution {
public:
    int dfs[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    void DFS(vector<vector<int>>& image, int sr, int sc, int color,vector<vector<int>>& sign,int row,int col,int oldcolor)
    {
        //渲染并做标记
        image[sr][sc]=color;
        sign[sr][sc]=1;
        //遍历sr,sc坐标的四个方向
        for(int i=0;i<4;i++)
        {
            int newsr=sr+dfs[i][0];
            int newsc=sc+dfs[i][1];
            //判断越界
            if(newsr>=row||newsr<0||newsc>=col||newsc<0)
                continue;
            if(image[newsr][newsc]==oldcolor&&sign[newsr][newsc]==0)
            {
                DFS(image,newsr,newsc,color,sign,row,col,oldcolor);
            }
        }

    }

    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
        if(image.empty())
            return image;
        int row=image.size();
        int col=image[0].size();
        int oldcolor=image[sr][sc];
        //这里的oldcolor是必须要传的,因为只有和image[sr][sc];相等的数才会被渲染
        vector<vector<int>> sign(row,vector<int>(col,0));
        //上面的数组用于标记,以防重复遍历
        DFS(image,sr,sc,color,sign,row,col,oldcolor);
        return image;
    }
};

被围绕的区域

给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。
【刷题篇】回溯算法(深度优先搜索(一))_第4张图片

思路:该题是和上一道题的解题步骤有一部分相似,该题是让找出被X包围的O,所以现在就先找出没有被包围的O做好标记,而O的四个方向也会被连起来导致不会被包围。标记的作用也是为了反复查找。

class Solution {
public:
    int next[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    void DFS(vector<vector<char>>& board,int row,int col,int curX,int curY)
    {
        //先将没有被包围的O进行标记,也是防止重复递归
        board[curX][curY]='A';
        for(int i=0;i<4;i++)
        {
            int newsr=curX+next[i][0];
            int newsc=curY+next[i][1];
            //判断越界
            if(newsr>=row||newsr<0||newsc>=col||newsc<0)
                continue;
            //挨着的O也是属于没有被包围的
            if(board[newsr][newsc]=='O')
                DFS(board,row,col,newsr,newsc);
        }
    }
    void solve(vector<vector<char>>& board) {
        int row=board.size();
        int col=board[0].size();
        //判断第一行和最后一行是否有O
        for(int j=0;j<col;j++)
        {
            if(board[0][j]=='O')
                DFS(board,row,col,0,j);
            if(board[row-1][j]=='O')
                DFS(board,row,col,row-1,j);
        }
        //判断第一列和最后一列是否有O
        for(int i=0;i<row;i++)
        {
            if(board[i][0]=='O')
                DFS(board,row,col,i,0);
            if(board[i][col-1]=='O')
                DFS(board,row,col,i,col-1);
        }
        //最后将A改回O,就是没有被包围的,将O改为X就是将包围的改为X
        for(int i=0;i<row;i++)
        {
            for(int j=0;j<col;j++)
            {
                if(board[i][j]=='O')
                    board[i][j]='X';
                if(board[i][j]=='A')
                    board[i][j]='O';
            }
        }
    }
};

你可能感兴趣的:(刷题篇,算法,深度优先,c++)