Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • 数组

    • 搜索

    • 二分查找

    • 排序

    • 边界判断

    • 双指针法

    • 连续子数组

    • 差分数组

    • 模拟

      • 1093. 大样本统计
      • 6910. 将数组划分成若干好子数组的方式
      • 1253. 重构 2 行二进制矩阵
      • 2532. 过桥的时间
      • 874. 模拟行走机器人
      • 189. 轮转数组
      • 649. Dota2 参议院
      • 剑指 Offer 14- II. 剪绳子 II
      • 剑指 Offer 20. 表示数值的字符串
      • LCP 41. 黑白翻转棋
        • 1.暴力枚举
        • 2.方向数组
      • 剑指 Offer 62. 圆圈中最后剩下的数字
      • 剑指 Offer 67. 把字符串转换成整数
    • 区间问题

  • 链表

  • 字符串

  • 二叉树

  • 动态规划

  • 深搜回溯

  • 数学贪心

  • 堆栈队列

  • 前缀和

  • 算法设计

  • 位运算

  • WA

  • 算法
  • 数组
  • 模拟
phan
2023-06-21
目录

LCP 41. 黑白翻转棋

# LCP 41. 黑白翻转棋 (opens new window)

# 1.暴力枚举

分析:枚举棋盘所有空的位置落黑子。落子后搜索当前可翻转的所有白子的数目,在cal中有如下细节:

  • 找到被包围的第一个白子。
  • 对于被“包裹”的白子,虽然有八个方向,但是每两个方向构成一个"包裹“,比如上和下,因此只需要搜索四个方向。同时根据i和j枚举的方向,作为包裹起点的四个方向分别是左、左上、上、右上。
  • 找到一个”包裹“样式后,将夹在中间的所有白子置为黑子。并计数。
  • 递归统计棋盘中被包围的所有白子。如果当前这轮递归统计的可翻转白子数目为0,说明此时已无白子可翻转,递归结束。
class Solution {
    int res=0;
    public int flipChess(String[] chessboard) {
        int[][] nums=new int[chessboard.length][chessboard[0].length()];
        for(int i=0;i<nums.length;i++){
            for(int j=0;j<nums[0].length;j++){
                //黑棋
                if(chessboard[i].charAt(j)=='X') nums[i][j]=1;
                //白棋
                if(chessboard[i].charAt(j)=='O') nums[i][j]=2;
            }
        }
        int[][] copy=new int[chessboard.length][chessboard[0].length()];
        for(int i=0;i<nums.length;i++){
            for(int j=0;j<nums[0].length;j++){
                if(nums[i][j]==0){
                    nums[i][j]=1;
                    copy(copy,nums);
                    cal(copy);
                    nums[i][j]=0;
                }
    }
    public int cal(int[][] nums){
        int temp=0;
        for(int i=0;i<nums.length;i++){
            for(int j=0;j<nums[0].length;j++){
                if(nums[i][j]==2){
                    //水平方向
                    if(isvalid(nums,i,j-1)&&nums[i][j-1]==1&&nums[i][j]==2){
                        int x=i,y=j+1;
                        boolean has=false;
                        while(isvalid(nums,x,y)){
                            if(nums[x][y]==0) break;
                            if(nums[x][y]==1){
                                has=true;
                                break;
                            }
                            y++;
                        }
                        if(has){
                            x=i;
                            y=j;
                            while(isvalid(nums,x,y)){
                                if(nums[x][y]==1) break;
                                nums[x][y]=1;
                                temp++;
                                y++;
                            }
                        }
                    }
                    //左上方向
                    if(isvalid(nums,i-1,j-1)&&nums[i-1][j-1]==1&&nums[i][j]==2){
                        int x=i+1,y=j+1;
                        boolean has=false;
                        while(isvalid(nums,x,y)){
                            if(nums[x][y]==0) break;
                            if(nums[x][y]==1){
                                has=true;
                                break;
                            }
                            y++;
                            x++;
                        }
                        if(has){
                            x=i;
                            y=j;
                            while(isvalid(nums,x,y)){
                                if(nums[x][y]==1) break;
                                nums[x][y]=1;
                                temp++;
                                y++;
                                x++;
                            }
                        }
                    }
                    //竖直方向
                    if(isvalid(nums,i-1,j)&&nums[i-1][j]==1&&nums[i][j]==2){
                        int x=i+1,y=j;
                        boolean has=false;
                        while(isvalid(nums,x,y)){
                            if(nums[x][y]==0) break;
                            if(nums[x][y]==1){
                                has=true;
                                break;
                            }
                            x++;
                        }
                        if(has){
                            x=i;
                            y=j;
                            while(isvalid(nums,x,y)){
                                if(nums[x][y]==1) break;
                                nums[x][y]=1;
                                temp++;
                                x++;
                            }
                        }
                    }
                    //右上方向
                    if(isvalid(nums,i-1,j+1)&&nums[i-1][j+1]==1&&nums[i][j]==2){
                        int x=i+1,y=j-1;
                        boolean has=false;
                        while(isvalid(nums,x,y)){
                            if(nums[x][y]==0) break;
                            if(nums[x][y]==1){
                                has=true;
                                break;
                            }
                            y--;
                            x++;
                        }
                        if(has){
                            x=i;
                            y=j;
                            while(isvalid(nums,x,y)){
                                if(nums[x][y]==1) break;
                                nums[x][y]=1;
                                temp++;
                                y--;
                                x++;
                            }
                        }
                    }
                }
            }
        }
        if(temp==0) return 0;
        int ans=temp+cal(nums);
        res=Math.max(res,ans);
        return ans;
    }
    public void copy(int[][]copy,int[][]nums){
        for(int i=0;i<nums.length;i++){
            for(int j=0;j<nums[0].length;j++){
                copy[i][j]=nums[i][j];
            }
        }
    }
    public boolean isvalid(int[][] nums,int x,int y){
        if(x<0||y<0||x>nums.length-1||y>nums[0].length-1) return false;
        return true;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

# 2.方向数组

使用方向数组控制每个方向上的搜索。

每次翻转白子变为黑子之后,将该位置加入队列中,判断该黑子的八个方向上是否存在新的可翻转的白子。

这种搜索策略相比前面对整个棋盘的递归而言,可以大大减少搜索次数。

int[][] dir=new int[][]{{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
1
编辑 (opens new window)
#Leetcode#模拟
上次更新: 2023/12/15, 15:49:57
剑指 Offer 20. 表示数值的字符串
剑指 Offer 62. 圆圈中最后剩下的数字

← 剑指 Offer 20. 表示数值的字符串 剑指 Offer 62. 圆圈中最后剩下的数字→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式