我有一个25x25网格,看起来像这样。在整个网格中,有两个randoms序列的字符串放置,我试图开发一些有效的方法来搜索网格并找到每个位置的点。
我已经查看了几个搜索2D数组的算法示例,而且大多数都专注于查找单个字符或数字等。
在此特定实例中,我可以使用哪种选项进行搜索?我在这样的时间搜索中实现了一个基本步骤:
public void search(String[][] grid) {
int cellsSearched = 0;
List<Point> cLocations = new ArrayList<>();
List<Point> sLocations = new ArrayList<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (cLocations.size() == 5 && sLocations.size() == 3) break;
if (grid[i][j].equals("S")) {
sLocations.add(new Point(i, j));
} else if (grid[i][j].equals("C")) {
cLocations.add(new Point(i, j));
}
cellsSearched++;
}
}
}
但这显然不是最有效的搜索方式。
我曾想过将网格划分为象限并一次搜索一个象限,但这似乎仍然存在太多潜在的缺陷。 (例如,两个序列都位于搜索的最后一个象限中。)
我的问题是,如何以尽可能少的步骤搜索此网格并收集其序列中每个字符的坐标?
答案 0 :(得分:1)
您可以使用一个技巧来改善搜索的运行时间。
但由于它是一个网格,并且由于我们没有关于'S'
和'C'
的展示位置的信息,因此时间复杂度将保持O(n^2)
。
除此之外,
一旦你点击'S'
或'C'
,你实际上可以从那里存储它们的整个序列。您基本上必须检查当前字符两侧是否有相同的字符并继续。
你可以有一个额外的2D
boolean
数组来跟踪ArrayList
中包含哪些点。
这是获得更好主意的代码:
public void search(String[][] grid) {
int cellsSearched = 0;
List<Point> cLocations = new ArrayList<>();
List<Point> sLocations = new ArrayList<>();
boolean[][] map = new boolean[grid.length][grid[0].length];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (cLocations.size() == 5 && sLocations.size() == 3) break;
if(!map[i][j]) {
if (grid[i][j].equals("S")) {
getSeries(i, j, "S", grid, map, sLocations);
} else if (grid[i][j].equals("C")) {
getSeries(i, j, "C", grid, map, sLocations);
}
}
cellsSearched++;
}
}
}
public boolean inbounds(int i, int j, String[][] grid) {
return ( 0 <= i && i < grid.length ) && ( 0 <= j && j < grid[i].length );
}
public void getSeries(int i, int j, String toFind,String[][] grid, boolean map[][], ArrayList<Point> locations) {
/**
* This function basically checks if 'i' and 'j' are safe so that accessing grid[i][j]
* would not cause ArrayOutOfBoundsException
*/
if(!inbounds(i, j, grid)) {
return;
}
String matched = grid[i][j];
if(!map[i][j] && matched.equals(toFind)) {
map[i][j] = true;
locations.add(new Point(i, j));
// Going up
getSeries(i - 1, j, toFind, grid, map, locations);
// Going down
getSeries(i + 1, j, toFind, grid, map, locations);
// Going left
getSeries(i, j - 1, toFind, grid, map, locations);
// Going right
getSeries(i, j + 1, toFind, grid, map, locations);
/*
(i+1, j-1) -> Going Bottom Left
(i+1, j+1) -> Going Bottom Right
(i-1, j-1) -> Going Top Left
(i-1, j+1) -> Going Top Right
*/
}
}
您看到,只要您点击'S'
或'C'
,getSeries
功能就会自动将整个序列保存到ArrayList
。
正如我前面提到的,时间复杂度仍为O(n^2)
,但肯定会减少查找序列的步骤数。