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

news/2024/7/20 21:09:19 标签: 宽度优先, 深度优先, 算法

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)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

http://www.niftyadmin.cn/n/456263.html

相关文章

华为OD机试真题 JavaScript 实现【高矮个子排队】【2023Q2 100分】,附详细解题思路

一、题目描述 现在有一队小朋友&#xff0c;他们高矮不同&#xff0c;我们以正整数数组表示这一队小朋友的身高&#xff0c;如数组{5,3,1,2,3}。 我们现在希望小朋友排队&#xff0c;以“高”“矮”“高”“矮”顺序排列&#xff0c;每一个“高”位置的小朋友要比相邻的位置高…

2023-06-21:redis中什么是BigKey?该如何解决?

2023-06-21&#xff1a;redis中什么是BigKey&#xff1f;该如何解决&#xff1f; 答案2023-06-21&#xff1a; 什么是bigkey bigkey是指存储在Key-Value数据库中的键对应的值所占用的内存空间较大。举个例子&#xff0c;如果值是字符串类型&#xff0c;它可以达到最大512MB的…

四、卷积神经网络整体基础结构

一、计算机发展应用 神经网络主要用于特征提取 卷积神经网络主要应用在图像领域&#xff0c;解决传统神经网络出现的过拟合、权重太多等风险 1&#xff0c;CV领域的发展 Computer vision计算机视觉的发展在2012年出现的AlexNet开始之后得到了挽救 之前都是一些传统的机器学习…

数字化如何推动快消品企业实现营销变革

近几年&#xff0c;不确定性在各行各业上演。尤其伴随新一代信息技术的快速发展&#xff0c;消费者的需求和购买渠道也在不断变化。这就要求企业需要通过对消费者潜在需求进行更加深度的挖掘&#xff0c;为消费者提供“更佳的体验”&#xff0c;从而释放消费能力。 在这样的大背…

如何做mysql调优?绝命7招,让慢SQL调优100倍

前言&#xff1a; 在40岁老架构师尼恩的读者社区&#xff08;50&#xff09;中&#xff0c;很多小伙伴拿不到offer&#xff0c;或者拿不到好的offer。 尼恩经常给大家 优化项目&#xff0c;优化简历&#xff0c;挖掘技术亮点。在指导简历的过程中&#xff0c; Java 调优是一项…

使用Servlet完成单表的增删改查功能以及使用模板方法设计模式解决类爆炸问题(重写service模板方法)

使用Servlet做一个单表的CRUD操作 开发前的准备 导入sql脚本创建一张部门表 drop table if exists dept; create table dept(deptno int primary key,dname varchar(255),loc varchar(255) ); insert into dept(deptno, dname, loc) values(10, XiaoShouBu, BeiJing); inser…

力扣周赛日记350

1. 前言 早上兴高采烈起床写周赛&#xff0c;结果写完两题开始坐牢。菜的很。 2. 赛题 LeetCode 第 350 场周赛 2.1 题1 LeetCode 6901. 总行驶距离 2.1.1 题意 卡车两个油箱&#xff0c;耗油1L行驶10km。油箱A耗5L,油箱B给邮箱A油1L。油箱A空后停止行驶&#xff0c;求可…

计算机组成原理绪论部分(题目总结)

&#xff11; &#xff0e;电子数字计算机和电子模拟计算机的区别在哪里&#xff1f; 解&#xff1a; 电子数字计算机中处理的信息是在时间上离散的数字量&#xff0c;运算的过程是不连续的&#xff1b; 电子模拟计算机中处理的信息是连续变化的物理量&#xff0c;运算的过程…