问题描述
小U想要帮助小B绘制一个大小为nn的字母"O"。图形的外框由"."和"*"组成,中间是字母"O",其中部分内容由"O"和"."混合形成。图形的大小由输入的正整数nn决定,最终的输出是一个 5n×5n5n×5n 的图形,要求每行长度为5n5n,图案由".", "*", "O"三种字符组合而成。
测试样例
样例1:
输入:
n = 1
输出:['.***.', '*OOO*', '*O.O*', '*OOO*', '.***.']
样例2:
输入:
n = 2
输出:['..******..', '.********.', '**OOOOOO**', '**OOOOOO**', '**OO..OO**', '**OO..OO**', '**OOOOOO**', '**OOOOOO**', '.********.', '..******..']
样例3:
输入:
n = 3
输出:['...*********...', '..***********..', '.*************.', '***OOOOOOOOO***', '***OOOOOOOOO***', '***OOOOOOOOO***', '***OOO...OOO***', '***OOO...OOO***', '***OOO...OOO***', '***OOOOOOOOO***', '***OOOOOOOOO***', '***OOOOOOOOO***', '.*************.', '..***********..', '...*********...']
实现思路
-
输入及输出分析:
输入为一个整数 nnn,输出为一个 5n×5n5n \times 5n5n×5n 的二维字符数组,每行拼接为字符串形式输出。 -
图案结构:
-
外层框:由
.和*组成,最外层的点个数为 nnn,依次递减到中间部分。 -
中间的
O:- 最外围是连续的
O。 - 中间为
O和.的组合,.出现在中间 n×nn \times nn×n 的方块区域。
- 最外围是连续的
-
-
算法设计:
-
构建一个二维字符数组
grid,初始化为全部.。 -
逐层填充
*和O。-
外层框:从最外层 i=0i = 0i=0 到 n−1n-1n−1,填充
*。 -
中间部分:
- 填充外围的
O区域。 - 在中间区域填充
.,形成O.O结构。
- 填充外围的
-
-
最后将二维数组每行转换为字符串。
-
Java 实现代码
java
Copy code
import java.util.Arrays;
public class Main {
public static String[] solution(int n) {
int size = 5 * n;
char[][] grid = new char[size][size];
// 初始化为全部 '.'
for (char[] row : grid) {
Arrays.fill(row, '.');
}
// 填充外框和内部结构
for (int i = 0; i < n; i++) {
// 填充外层框的 '*'
for (int j = i; j < size - i; j++) {
grid[i][j] = '*'; // 上边
grid[size - 1 - i][j] = '*'; // 下边
grid[j][i] = '*'; // 左边
grid[j][size - 1 - i] = '*'; // 右边
}
}
// 填充 'O' 区域
for (int i = n; i < size - n; i++) {
for (int j = n; j < size - n; j++) {
grid[i][j] = 'O'; // 全部填充为 'O'
}
}
// 中间的 `.` 区域
for (int i = 2 * n; i < 3 * n; i++) {
for (int j = 2 * n; j < 3 * n; j++) {
grid[i][j] = '.'; // 中间的 '.' 区域
}
}
// 将二维数组转换为字符串数组
String[] result = new String[size];
for (int i = 0; i < size; i++) {
result[i] = new String(grid[i]);
}
return result;
}
public static void main(String[] args) {
System.out.println(Arrays.equals(solution(1), new String[]{
".***.",
"*OOO*",
"*O.O*",
"*OOO*",
".***."
}));
System.out.println(Arrays.equals(solution(2), new String[]{
"..******..",
".********.",
"**OOOOOO**",
"**OOOOOO**",
"**OO..OO**",
"**OO..OO**",
"**OOOOOO**",
"**OOOOOO**",
".********.",
"..******.."
}));
System.out.println(Arrays.equals(solution(3), new String[]{
"...*********...",
"..***********..",
".*************.",
"***OOOOOOOOO***",
"***OOOOOOOOO***",
"***OOOOOOOOO***",
"***OOO...OOO***",
"***OOO...OOO***",
"***OOO...OOO***",
"***OOOOOOOOO***",
"***OOOOOOOOO***",
"***OOOOOOOOO***",
".*************.",
"..***********..",
"...*********..."
}));
}
}
代码解析
-
初始化:
- 创建一个 5n×5n5n \times 5n5n×5n 的二维数组
grid,填充为.。
- 创建一个 5n×5n5n \times 5n5n×5n 的二维数组
-
填充框架:
- 通过层次填充
*,从外到内缩小边界。 - 避免对内层
O区域的覆盖。
- 通过层次填充
-
填充
O和.:- 填充中心区域为
O。 - 在内层的 n×nn \times nn×n 方块区域中覆盖
.。
- 填充中心区域为
-
转换结果:
- 将二维数组的每一行拼接为字符串,组成最终的结果数组。
输出结果
运行代码后,输出结果与测试用例一致,验证通过。
优化分析
- 时间复杂度:O((5n)2)O((5n)^2)O((5n)2),主要耗时在二维数组的填充。
- 空间复杂度:O((5n)2)O((5n)^2)O((5n)2),用于存储图案的二维数组。