算法营day17--回溯

力扣 200 岛屿的数量

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:
[
[‘1’,‘1’,‘1’,‘1’,‘0’],
[‘1’,‘1’,‘0’,‘1’,‘0’],
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘0’,‘0’,‘0’,‘0’,‘0’]
]
输出: 1

示例 2:

输入:
[
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘0’,‘0’,‘1’,‘0’,‘0’],
[‘0’,‘0’,‘0’,‘1’,‘1’]
]
输出: 3
解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-islands
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
遍历二维矩阵,碰到1的话,就DFS(注意边界的控制)。在DFS中访问1的时候,将访问过的1置为0,以作为标记。遍历的时候碰到一个一,就累加计数一次。
代码:

int nexP[4][2] = {
    
    {
    
    0,1},{
    
    0,-1},{
    
    -1,0},{
    
    1,0}};//上下左右
class Solution {
    
    
public:
    void DFS(vector<vector<char>>& grid, int row, int col,int x, int y ){
    
    
        for(int k = 0; k < 4;++k){
    
    
            int nX = x +nexP[k][0];
            int nY = y +nexP[k][1];
            if(nX >= row || nX <0 || nY >= col || nY < 0)
                continue;//越界的话,就继续判断下一个点
            if(grid[nX][nY] == '1'){
    
    
                grid[nX][nY] ='0';//将访问过的'1'变为'0'
                DFS(grid,row,col,nX,nY);
            }
        }
    }
    int numIslands(vector<vector<char>>& grid) {
    
    
        if(grid.empty())
            return 0;
        int ret = 0;
        int row = grid.size();
        int col = grid[0].size();
        for(int i = 0;i<row;++i){
    
    
            for(int j =0;j<col;++j){
    
    
                if(grid[i][j] == '1')
                {
    
    
                    ++ret;
                    DFS(grid,row,col,i,j);
                }
            }
        }
        return ret;
    }
};

力扣 17 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
在这里插入图片描述

示例:

输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].

说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
根据数字找到其对应的字符串,取一个字符加到原来的后面,DFS直到digitInx到数字字符串的尾部返回。
代码:

map<char, string> numMap = {
    
    {
    
    '2',"abc"},{
    
    '3',"def"},{
    
    '4',"ghi"},{
    
    '5',"jkl"}
,{
    
    '6',"mno"},{
    
    '7',"pqrs"},{
    
    '8', "tuv"},{
    
    '9',"wxyz"}};
class Solution {
    
    
public:
    void DFS(string& digits, vector<string>& allRet, string curStr, int digitInx){
    
    
        if(digitInx == digit.size()){
    
    
            allRet.push_back(curStr);
            return;
        }
        string strMap = numMap[digits[digitInx]];
        for(char ch : strMap){
    
    
            DFS(digit, allRet,curStr + ch,digitInx + 1);
        }
    }
    vector<string> letterCombinations(string digits) {
    
    
        vector<string> vec;
        if(digits.empty())
            return vec;
        DFS(digits,vec,"",0);
        return vec;
    }
};

力扣 130 被围绕的区域

给定一个二维的矩阵,包含 ‘X’ 和 ‘O’(字母 O)。

找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。

示例:

X X X X
X O O X
X X O X
X O X X

运行你的函数后,矩阵变为:

X X X X
X X X X
X X X X
X O X X

解释:

被围绕的区间不会存在于边界上,换句话说,任何边界上的 ‘O’ 都不会被填充为 ‘X’。 任何不在边界上,或不与边界上的 ‘O’ 相连的 ‘O’ 最终都会被填充为 ‘X’。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/surrounded-regions
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
PS:手贱啊,else if()后面多打了个分号,debug了一个小时
遍历矩阵的边界,将与边界联通的’O’都置为’A’。遍历矩阵将里面的’O’都变为’X’,把’A’变为’O’
代码:

int nextP[4][2] ={
    
    {
    
    0,1},{
    
    1,0},{
    
    0,-1},{
    
    -1,0}};
class Solution {
    
    
public:
    void DFS(vector<vector<char>>& board, int row, int col,int curX, int curY){
    
    
        //标记此位置为A
        //if(board[curX][curY] == 'O')
        board[curX][curY] = 'A';
        for(int i = 0;i < 4;++i){
    
    
            int newX = curX + nextP[i][0];
            int newY = curY + nextP[i][1];
            //判读是否越界
            if(newX >= row || newX < 0 || newY >= col || newY < 0)
                continue;
            //判断新的位置是否为O
            if(board[newX][newY] == 'O')
                DFS(board,row,col,newX,newY);  
        }   
    }
    void solve(vector<vector<char>>& board) {
    
    
        if(board.empty())
            return;
        int row = board.size();
        int col = board[0].size();
        //搜索四个边的点
        //第一行,最后一行
        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);
        }
        //第一列、最后一列
        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);
        }
        for(int i = 0; i<row;++i){
    
    
            for(int j = 0;j < col;++j){
    
    
                if(board[i][j] == 'A')
                    board[i][j] = 'O';
                else if(board[i][j] == 'O')
                    board[i][j] = 'X';
            }
        }
    }
};

力扣 733 图像渲染

有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。

给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。

为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

最后返回经过上色渲染后的图像。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flood-fill
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

int nexP[4][2] = {
    
    {
    
    0,1},{
    
    0,-1},{
    
    -1,0},{
    
    1,0}};
class Solution {
    
    
public:
    void DFS(vector<vector<int>>& image,int r,int c,int newColor,int color){
    
    
        if(r >= image.size() || c >= image[0].size())
            return;
        if(image[r][c] != color)
            return;
        image[r][c] = newColor;
        for(int i = 0;i<4;++i){
    
    
            int newr = r + nexP[i][0];
            int newc = c + nexP[i][1];
            DFS(image,newr,newc,newColor,color);
        }
    }
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
    
    
        int color = image[sr][sc];
        if(color == newColor)
            return image;
        DFS(image,sr,sc,newColor,color);
        return image;
    }
};

下面这种实现形式,搞太复杂了。以为有个book标记会提高效率,完全没啥影响么。

int nexP[4][2] = {
    
    {
    
    0,1},{
    
    0,-1},{
    
    -1,0},{
    
    1,0}};
class Solution {
    
    
public:
    void DFS(vector<vector<int>>& image,int r,int c,int row,int col,vector<vector<int>>& book,int newColor,int oldcolor){
    
    
        image[r][c] = newColor;
        book[r][c] = 1;
        for(int i = 0;i<4;++i){
    
    
            int newr = r + nexP[i][0];
            int newc = c + nexP[i][1];
            //判断是否越界
            if(newr >= row || newr < 0
            || newc >= col ||newc < 0)
                continue;
            //判断是否需要渲染
            if(image[newr][newc] == oldcolor && book[newr][newc] == 0)
                DFS(image,newr,newc,row,col,book,newColor,oldcolor);
        }
    }
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
    
    
        if(image.empty())
            return image;
        //获取旧的颜色
        int oldcolor = image[sr][sc];
        if(oldcolor == newColor)
            return image;
        int row = image.size();
        int col = image[0].size();
        //建立标记
        vector<vector<int>> book(row,vector<int>(col,0));
        DFS(image,sr,sc,row,col,book,newColor,oldcolor);
        return image;
    }
};

力扣 39 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。 

示例 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]

示例 2:

输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

提示:

1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
代码:

力扣 1079 活字印刷

你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。

注意:本题中,每个活字字模只能使用一次。

示例 1:

输入:“AAB”
输出:8
解释:可能的序列为 “A”, “B”, “AA”, “AB”, “BA”, “AAB”, “ABA”, “BAA”。

示例 2:

输入:“AAABBC”
输出:188

提示:

1 <= tiles.length <= 7
tiles 由大写英文字母组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/letter-tile-possibilities
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
代码:

猜你喜欢

转载自blog.csdn.net/qq_35353824/article/details/107813650