我需要一种在矩阵中找到一系列连续数字的方法,并将其替换为1,将所有其他数字替换为0,移动就好像是一条蛇。让我举一个例子,希望能让它更容易理解:
9 2 9
9 6 8
9 9 4
这个矩阵应该变成:
1 0 0
1 0 0
1 1 0
现在我拥有的是:
public int[][] replace(int[][] numbers, int n) {
int[][] temp = numbers;
int cont = 0;
int cont2 = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < n - 1 && temp[cont][cont2] == temp[cont + 1][cont2]) {
numbers[cont][cont2] = 1;
numbers[cont + 1][cont2] = 1;
cont++;
}
if (j < n - 1 && temp[cont][cont2] == temp[cont][cont2 + 1]) {
numbers[0][1] = 1;
numbers[0][0] = 1;
cont2++;
}
}
cont2 = 0;
}
return numbers;
}
它只能起作用,只取代前两个值,然后由于某种原因停止这样做。我还缺少验证,以检查当前号码左侧的数字;以及使所有其他数字0不应该太难的部分。
任何人都有任何想法,我需要改变什么来使这项工作?
答案 0 :(得分:0)
问题的规范已经包含一个问题:当有两行数字时该怎么办?使用DFS(或者BFS)或任何其他路径查找算法可以非常简单地找到解决方案本身。虽然这个主题很好,所以我不会在这里发布任何代码。
答案 1 :(得分:0)
很难说,因为您的意图令人困惑,但在for
循环中,您有两个连续的if
语句。由于第一个语句可以更改第二个语句的条件表达式中使用的变量的值,我想知道你是否应该在第二个语句中使用else
而不是if
?
答案 2 :(得分:0)
首先,我发现了一些问题,或者我误解了算法中的一些要点:
public int[][] replace(int[][] numbers, int n) {
int[][] temp = numbers; // /!\ temp points to the same array as numbers
int cont = 0; // why not using i
int cont2 = 0; // why not using j
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < n - 1 && temp[cont][cont2] == temp[cont + 1][cont2]) {
numbers[cont][cont2] = 1; // /!\ temp=numbers is also modified
numbers[cont + 1][cont2] = 1;
cont++; // /!\ ~= i*j => index out of bound
}
if (j < n - 1 && temp[cont][cont2] == temp[cont][cont2 + 1]) {
numbers[0][1] = 1; // why fixed indexes ?
numbers[0][0] = 1;
cont2++;
}
}
cont2 = 0; // cont2 seems equivalent to j
}
return numbers;
}
你想要这样的东西(我还没有测试过它):
public int[][] replace(int[][] numbers, int n) {
int[][] result=new int[n][n];
int ref = numbers[0][0];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (numbers[i][j]==ref) {
boolean isAdj=false;
if(i>0) isAdj=isAdj || numbers[i-1][j]==ref;
if(i<n-1) isAdj=isAdj || numbers[i+1][j]==ref;
if(j>0) isAdj=isAdj || numbers[i][j-1]==ref;
if(j<n-1) isAdj=isAdj || numbers[i][j+1]==ref;
if(isAdj) result[i][j]=1;
}
}
}
return result;
}
答案 3 :(得分:0)
您当前的整体想法(据我所知,无论您的代码中存在哪些错误)都是在单个路径中查找类似的数字,只会向下和向右。这个想法在所有情况下都不适用。如果你遇到一个数字块然后上升,那么它不会改变所有数字。例如,给定
2 1 2
2 1 2
2 2 2
您的算法将从左上角开始向下然后向右移动,但不会返回以完成U形。
其次,行int[][] temp = numbers;
表示您对temp
所做的任何更改都会发送到numbers
,反之亦然。它被称为浅拷贝,因为只复制了引用,而不是它们引用的数据。您可能需要深层复制。
简单的答案是使用泛洪填充算法。洪水填充基本上填充任意区域,通过尽可能多地搜索整个板,同时遵循定义要填充的区域的规则。它可以在任何地方成功探索,它会在该位置删除“面包屑”(特殊值),然后您可以返回并将其更改为任何需要的位置。
以下洪水填充算法使用深度优先搜索来探索要填充的区域。如果要进行广度优先搜索,只需将堆栈切换为优先级队列。
import java.awt.Point; //just an integer based point object for the Stack
import java.util.Stack; //get the Stack
public int[][] replace(int[][] numbers, int n) {
int value = numbers[0][0]; //value we are looking for
int[] rowChange = {-1, 0, 1, 0}; //for easy direction checking
int[] colChange = {0, 1, 0, -1};
// for the breadcrumbs; initialized to 0, so make a breadcrumb equal to 1
// then the resulting breadcrumb matrix will be what you want
int[][] breadcrumbs = new int[numbers.length][numbers[0].length];
Stack<Point> toExplore = new Stack<Point>();
toExplore.push(new Point(0, 0)); //explore the first point
// we are using Point.y as the row (first index),
// and Point.x as the column (second index)
//while there is a location to explore
while (toExplore.size() > 0) {
Point center = toExplore.pop();
// drop a breadcrumb
breadcrumbs[center.y][center.x] = 1;
// explore in the 4 cardinal directions
for (int i = 0; i < 4; i++) {
int row = center.y + rowChange[i];
int col = center.x + colChange[i];
// make sure we haven't already been here (bounds check first)
if ((row >= 0) && (row < numbers.length) && // bounds check
(col >= 0) && (col < numbers[0].length) &&
(breadcrumbs[row][col] == 0) && // make sure we haven't been there already
(numbers[row][col] == value)) // make sure it has the right value there
{
toExplore.push(new Point(col, row));
}
}
}
// filled with 1's where we explored and 0's where we didn't
return breadcrumbs;
}
<强>更新强> 构建并运行代码,它可以工作。