【每日一题Day244】LCP 41. 黑白翻转棋 bfs dfs

简介: 【每日一题Day244】LCP 41. 黑白翻转棋 bfs dfs

LCP 41. 黑白翻转棋

n*m 大小的棋盘中,有黑白两种棋子,黑棋记作字母 "X", 白棋记作字母 "O",空余位置记作 "."。当落下的棋子与其他相同颜色的棋子在行、列或对角线完全包围(中间不存在空白位置)另一种颜色的棋子,则可以翻转这些棋子的颜色。

  • 思路
    枚举棋盘中每一个未下棋的位置,求出在该位置下黑子时,能够反转的白子数目,取最大值返回即可。对于每一个位置需要求出八个方向末尾是黑子的连续白子数目,并且如果将一个白子反转为黑子后,还需要搜索该位置延伸出去能够翻转的白子数目,故而可以使用bfs或者dfs实现
bfs
  • 实现
    将每个方向的可以反转的白子加入队列中
class Solution {
    String[] chessboard;
    int[][] dirs = {{0, 1},{0, -1}, {1, 0}, {-1, 0}, {1, -1}, {1, 1},{-1, 1}, {-1, -1}};
    int m, n;
    public int flipChess(String[] chessboard) {
        m = chessboard.length;
        n = chessboard[0].length();
        this.chessboard = chessboard;
        int res = 0;
        for (int i = 0; i < m; i++){
            for (int j = 0; j < n; j++){
                if (chessboard[i].charAt(j) == '.'){
                    res = Math.max(res, bfs(i, j));
                }
            }
        }
        return res;
    }
    // 使用bsf搜索在位置(x,y)下黑子时,能够反转的白子数目
    // 将白子放入队列中,搜索八个方向末尾是黑子的连续白子数目
    // 如果下一个位置是白子,那么继续放入队列
    // 如果下一个位置是黑子,那么记录连续白子数目
    // 如果下一个位置没有子,那么忽略不计
    public int bfs(int x, int y){
        char[][] chess = new char[m][n];       
        for (int i = 0; i < m; i++){
            chess[i] = chessboard[i].toCharArray();
        }
        int res = 0;
        Deque<int[]> queue = new LinkedList<>();
        queue.addLast(new int[]{x, y});
        chess[x][y] ='X';
        while (!queue.isEmpty()){
            int[] loc = queue.pollFirst();
            x = loc[0];
            y = loc[1];
            for (int k = 0; k < 8; k++){
                int i = x + dirs[k][0] , j = y + dirs[k][1];
                while (i >= 0 && i < m && j >= 0 && j < n && chess[i][j] == 'O'){
                    i += dirs[k][0];
                    j += dirs[k][1];
                }
                if (i >= 0 && i < m && j >= 0 && j < n && chess[i][j] == 'X'){
                    i -= dirs[k][0];
                    j -= dirs[k][1];
                    res += Math.max(Math.abs(x - i), Math.abs(y - j));
                    while (x != i || y != j){
                        chess[i][j] = 'X';
                        queue.addLast(new int[]{i, j});
                        i -= dirs[k][0];
                        j -= dirs[k][1];
                    }
                }
            }
        }
        return res;
    }
}
dfs
  • 实现
    使用额外数组记录每个方向可以反转的白子位置,再进行dfs
class Solution {
        char[][] cb;
        int m,n;
        int ans = 0;
        int[] directions = new int[]{-1,-1,0,1,1,-1,1,0,-1};
        public int flipChess(String[] chessboard) {
            m = chessboard.length;
            n = chessboard[0].length();
            this.cb = new char[m][n];
            for(int i = 0; i < m; i++){
                for(int j = 0; j < n; j++){
                    if(chessboard[i].charAt(j)=='.'){
                        for(int t = 0; t < m; t++){
                            cb[t] = chessboard[t].toCharArray();
                        }
                        ans = Math.max(ans,dfs(i,j));
                    }
                }
            }
            return ans;
        }
        private int dfs(int i, int j){
            List<int[]> nexts = new ArrayList<>();
            for(int index = 0; index < 8; index++){
                int x = i+directions[index];
                int y = j+directions[index+1];
                List<int[]> tmp = new ArrayList<>();
                while(x>=0&&x<m&&y>=0&&y<n&&cb[x][y]=='O'){
                    tmp.add(new int[]{x,y});
                    x+=directions[index];
                    y+=directions[index+1];
                }
                if(x>=0&&x<m&&y>=0&&y<n&&cb[x][y]=='X'){
                    nexts.addAll(tmp);
                }
            }
            for(int[] next:nexts){
                cb[next[0]][next[1]] = 'X';
            }
            int ans = nexts.size();
            for(int[] next:nexts){
                ans += dfs(next[0],next[1]);
            }
            return ans;
        }
    }
作者:钰娘娘丿-曱-乀
链接:https://leetcode.cn/problems/fHi6rV/solutions/2315793/yu-niang-niang-lcp-41-hei-bai-fan-zhuan-yv1s6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


目录
相关文章
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
|
6月前
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
|
6月前
|
算法
一题学会BFS和DFS,手撕不再怕
一题学会BFS和DFS,手撕不再怕
|
6月前
|
机器学习/深度学习 人工智能 算法
LeetCode刷题--- 面试题 01.07. 旋转矩阵(原地旋转+翻转替旋转)
LeetCode刷题--- 面试题 01.07. 旋转矩阵(原地旋转+翻转替旋转)
【LeetCode-每日一题】-120. 三角形最小路径和
【LeetCode-每日一题】-120. 三角形最小路径和
|
存储 算法
每日刷题(翻转+二分+BFS)
每日刷题(翻转+二分+BFS)
|
机器学习/深度学习 定位技术
【每日一题Day109】LC1210穿过迷宫的最少移动次数 | BFS+dp
思路:使用BFS搜索,队列中存放三元组[蛇尾的横轴坐标x,蛇尾的纵轴坐标y,蛇的状态],当蛇为水平时,状态为0;当蛇为竖直时,状态为1
130 1
【每日一题Day109】LC1210穿过迷宫的最少移动次数 | BFS+dp
洛谷P1162 填涂颜色——广搜
洛谷P1162 填涂颜色——广搜
74 0
|
存储
Leetcode-每日一题1210. 穿过迷宫的最少移动次数(BFS)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_46618592/article/details/128890280?spm=1001.2014.3001.5501
117 0
Leetcode-每日一题1210. 穿过迷宫的最少移动次数(BFS)
|
机器学习/深度学习
【每日一题Day107】LC1145二叉树着色游戏 | dfs+贪心
现在,假设你是「二号」玩家,根据所给出的输入,假如存在一个 y 值可以确保你赢得这场游戏,则返回 true ;若无法获胜,就请返回 false 。
98 0
【每日一题Day107】LC1145二叉树着色游戏 | dfs+贪心