题目描述
给一个字符串和一个二维字符数组,如果该字符串存在于该数组中,则按字符串的字符顺序输出字符串每个字符所在单元格的位置下标字符串,如果找不到返回字符串“N”。
1.需要按照字符串的字符组成顺序搜索,且搜索到的位置必须是相邻单元格,其中“相邻单元格”是指那些水平相邻或垂直相邻的单元格。
2.同一个单元格内的字母不允许被重复使用。
3.假定在数组中最多只存在一个可能的匹配。
输入描述
第1行为一个数字N指示二维数组在后续输入所占的行数。
第2行到第N+1行输入为一个二维大写字符数组,每行字符用半角,分割。
第N+2行为待查找的字符串,由大写字符组成。
二维数组的大小为N*N,0<N<=100。
单词长度K,0<K<1000。
输出描述
输出一个位置下标字符串,拼接格式为:第1个字符行下标+”,”+第1个字符列下标+”,”+第2个字符行下标+”,”+第2个字符列下标… +”,”+第N个字符行下标+”,”+第N个字符列下标。
用例
输入 | 4 A,C,C,F C,D,E,D B,E,S,S F,E,C,A ACCESS |
输出 | 0,0,0,1,0,2,1,2,2,2,2,3 |
说明 | ACCESS分别对应二维数组的[0,0] [0,1] [0,2] [1,2] [2,2] [2,3]下标位置。 |
这个问题的核心是从二维字符数组中找到一个特定的字符串,并确定字符串中的每个字符在数组中的位置。字符在数组中必须按照字符串的顺序,并且必须是相邻的单元格。相邻的定义包括水平和垂直相邻,不能重复使用相同的单元格。
题目解析
-
输入解析:
- 二维数组: 从第一行到第N+1行,每行包含N个字符。
- 待查找的字符串: 在第N+2行给出。
-
目标:
- 如果找到该字符串,返回每个字符的坐标。坐标的输出格式为
row1,col1,row2,col2,...
。 - 如果找不到该字符串,返回
N
。
- 如果找到该字符串,返回每个字符的坐标。坐标的输出格式为
-
约束:
- 查找的字符必须是相邻的,包括水平和垂直方向。
- 单元格不能重复使用。
解题步骤
-
遍历二维数组:
- 对每个单元格进行深度优先搜索 (DFS),尝试从每个单元格开始匹配字符串。
-
深度优先搜索 (DFS):
- 从当前单元格出发,尝试找到字符串中的下一个字符。
- 确保下一个字符在相邻的单元格中,并且单元格没有被重复使用。
- 记录已找到的字符位置。
-
坐标记录和输出:
- 如果匹配成功,记录路径上的坐标。
- 如果遍历完所有可能的起点都没有找到匹配,则输出
N
。
JAVA算法源码
import java.util.*;
public class WordSearch {
private static final int[] ROW_DIRS = {0, 0, 1, -1}; // 右, 左, 下, 上
private static final int[] COL_DIRS = {1, -1, 0, 0};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = Integer.parseInt(scanner.nextLine().trim());
char[][] grid = new char[N][N];
for (int i = 0; i < N; i++) {
String[] row = scanner.nextLine().trim().split(",");
for (int j = 0; j < N; j++) {
grid[i][j] = row[j].charAt(0);
}
}
String word = scanner.nextLine().trim();
List<String> result = findWordInGrid(grid, N, word);
if (result.isEmpty()) {
System.out.println("N");
} else {
System.out.println(String.join(",", result));
}
}
private static List<String> findWordInGrid(char[][] grid, int N, String word) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (grid[i][j] == word.charAt(0)) {
boolean[][] visited = new boolean[N][N];
List<String> path = new ArrayList<>();
if (search(grid, N, word, 0, i, j, visited, path)) {
return path;
}
}
}
}
return new ArrayList<>();
}
private static boolean search(char[][] grid, int N, String word, int index, int row, int col, boolean[][] visited, List<String> path) {
if (index == word.length()) {
return true;
}
if (row < 0 || col < 0 || row >= N || col >= N || visited[row][col] || grid[row][col] != word.charAt(index)) {
return false;
}
visited[row][col] = true;
path.add(row + "," + col);
for (int i = 0; i < 4; i++) {
int newRow = row + ROW_DIRS[i];
int newCol = col + COL_DIRS[i];
if (search(grid, N, word, index + 1, newRow, newCol, visited, path)) {
return true;
}
}
visited[row][col] = false;
path.remove(path.size() - 1);
return false;
}
}
解释
-
数据输入:
- 通过
Scanner
读取输入的二维数组和待查找的字符串。
- 通过
-
深度优先搜索 (DFS):
search
方法用于递归地寻找字符串,记录路径。
-
路径记录:
path
列表记录找到的字符坐标。
-
输出:
- 如果找到字符串,按要求格式化输出坐标。如果没有找到,输出
"N"
。
- 如果找到字符串,按要求格式化输出坐标。如果没有找到,输出
这个代码实现了从二维数组中查找字符串并返回字符位置的需求,符合题目的所有要求。
JS算法源码
function findWordInGrid(grid, word) {
const N = grid.length;
const directions = [
[0, 1], // 右
[0, -1], // 左
[1, 0], // 下
[-1, 0] // 上
];
function isValid(x, y) {
return x >= 0 && x < N && y >= 0 && y < N;
}
function search(x, y, index, visited, path) {
if (index === word.length) {
return true;
}
if (!isValid(x, y) || visited[x][y] || grid[x][y] !== word[index]) {
return false;
}
visited[x][y] = true;
path.push(`${x},${y}`);
for (const [dx, dy] of directions) {
const newX = x + dx;
const newY = y + dy;
if (search(newX, newY, index + 1, visited, path)) {
return true;
}
}
visited[x][y] = false;
path.pop();
return false;
}
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
if (grid[i][j] === word[0]) {
const visited = Array.from({ length: N }, () => Array(N).fill(false));
const path = [];
if (search(i, j, 0, visited, path)) {
return path.join(',');
}
}
}
}
return 'N';
}
// 示例用法
const grid = [
['A', 'B', 'C', 'E'],
['S', 'F', 'C', 'S'],
['A', 'D', 'E', 'E']
];
const word = 'ABCCED';
console.log(findWordInGrid(grid, word)); // 输出: "0,0,0,1,0,2,1,2,2,2,2,1"
代码解释
-
findWordInGrid
:- 主函数,接受二维数组
grid
和待查找的字符串word
。 N
是网格的尺寸。- 定义了四个方向:右、左、下、上。
- 主函数,接受二维数组
-
isValid
:- 检查坐标
(x, y)
是否在网格范围内。
- 检查坐标
-
search
:- 深度优先搜索函数,尝试从
(x, y)
开始匹配word
中的字符。 - 使用
visited
数组避免重复使用单元格。 - 如果匹配成功,将路径添加到
path
中并返回true
。 - 如果匹配失败,回溯(即撤销当前路径并继续搜索)。
- 深度优先搜索函数,尝试从
-
for
循环:- 遍历二维数组的每个单元格,如果该单元格的字符与
word
的第一个字符匹配,则启动search
函数。 - 如果找到了匹配的路径,返回路径坐标的逗号分隔字符串;如果没有找到,返回
'N'
。
- 遍历二维数组的每个单元格,如果该单元格的字符与
这段代码可以用于在二维字符网格中查找字符串并获取字符位置,如果无法找到字符串则返回 'N'
。
Pyhton算法源码
def find_word_in_grid(grid, word):
N = len(grid)
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
def is_valid(x, y):
return 0 <= x < N and 0 <= y < N
def search(x, y, index, visited, path):
if index == len(word):
return True
if not is_valid(x, y) or visited[x][y] or grid[x][y] != word[index]:
return False
visited[x][y] = True
path.append((x, y))
for dx, dy in directions:
new_x, new_y = x + dx, y + dy
if search(new_x, new_y, index + 1, visited, path):
return True
visited[x][y] = False
path.pop()
return False
for i in range(N):
for j in range(N):
if grid[i][j] == word[0]:
visited = [[False] * N for _ in range(N)]
path = []
if search(i, j, 0, visited, path):
return ','.join(f'{x},{y}' for x, y in path)
return 'N'
# 示例用法
grid = [
['A', 'B', 'C', 'E'],
['S', 'F', 'C', 'S'],
['A', 'D', 'E', 'E']
]
word = 'ABCCED'
print(find_word_in_grid(grid, word)) # 输出: "0,0,0,1,0,2,1,2,2,2,2,1"
is_valid
: 检查坐标是否在网格内。search
: 深度优先搜索,尝试从(x, y)
开始匹配word
中的字符。使用visited
数组来避免重复访问单元格,path
存储当前路径。find_word_in_grid
: 遍历网格的每个单元格,如果匹配word
的第一个字符,调用search
进行深度优先搜索。返回路径的逗号分隔字符串,如果没有找到,返回'N'
。
C算法源码
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define N 3
bool is_valid(int x, int y) {
return x >= 0 && x < N && y >= 0 && y < N;
}
bool search(char grid[N][N], int x, int y, int index, char *word, bool visited[N][N], int path_x[], int path_y[], int *path_index) {
if (index == strlen(word)) {
return true;
}
if (!is_valid(x, y) || visited[x][y] || grid[x][y] != word[index]) {
return false;
}
visited[x][y] = true;
path_x[*path_index] = x;
path_y[*path_index] = y;
(*path_index)++;
int directions[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
for (int i = 0; i < 4; i++) {
int new_x = x + directions[i][0];
int new_y = y + directions[i][1];
if (search(grid, new_x, new_y, index + 1, word, visited, path_x, path_y, path_index)) {
return true;
}
}
visited[x][y] = false;
(*path_index)--;
return false;
}
void find_word_in_grid(char grid[N][N], char *word) {
bool visited[N][N] = { false };
int path_x[N * N];
int path_y[N * N];
int path_index;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (grid[i][j] == word[0]) {
path_index = 0;
if (search(grid, i, j, 0, word, visited, path_x, path_y, &path_index)) {
for (int k = 0; k < path_index; k++) {
printf("%d,%d", path_x[k], path_y[k]);
if (k < path_index - 1) {
printf(",");
}
}
printf("\n");
return;
}
}
}
}
printf("N\n");
}
int main() {
char grid[N][N] = {
{'A', 'B', 'C'},
{'S', 'F', 'C'},
{'A', 'D', 'E'}
};
char word[] = "ABCCED";
find_word_in_grid(grid, word); // 输出: "0,0,0,1,0,2,1,2,2,2,2,1"
return 0;
}
is_valid
: 检查坐标是否在网格内。search
: 深度优先搜索,类似于 Python 实现。使用visited
数组避免重复访问单元格,path_x
和path_y
存储当前路径的坐标。find_word_in_grid
: 遍历网格的每个单元格,调用search
进行深度优先搜索。输出路径的坐标字符串,如果没有找到,输出'N'
。