Java 如何处理列表整数列表并查找邻居?
我目前正在尝试解决一个问题,输入应该如下Java 如何处理列表整数列表并查找邻居?,java,algorithm,data-structures,runtime,time-complexity,Java,Algorithm,Data Structures,Runtime,Time Complexity,我目前正在尝试解决一个问题,输入应该如下 int hours(int rows, int columns, List<List<Integer> > grid) 每个值表示网络中一台相互发送文件的机器,因此如果该值为“1”,则该节点能够将文件发送到所有邻居(对角值不仅计算向上/向下/向右/向左)。问题是一旦0变为1(受邻居单元影响)它无法在1小时前将文件发送给任何其他邻居 问题的目标是返回在所有节点接收文件之前需要多少小时?(换句话说,考虑到运行时复杂性,所有矩阵变为1
int hours(int rows, int columns, List<List<Integer> > grid)
每个值表示网络中一台相互发送文件的机器,因此如果该值为“1”,则该节点能够将文件发送到所有邻居(对角值不仅计算向上/向下/向右/向左)。问题是一旦0变为1(受邻居单元影响)它无法在1小时前将文件发送给任何其他邻居
问题的目标是返回在所有节点接收文件之前需要多少小时?(换句话说,考虑到运行时复杂性,所有矩阵变为1。
视觉解释:(在第一个小时后,这应该是被视为迭代的矩阵状态):
因此,我采用了一种方法,在提供的网格中遍历矩阵并在临时数组中追加值(因为我不知道如何更新或追加主列表中的列表值)。然后,一旦行索引达到最大值,我向int变量添加1小时,并向主网格添加值
我知道下面的代码还没有运行/完成,可能有语法错误,但你明白了想法和方法
我的问题是,有没有比我更简单、更有效的方法?我也找到了一个解决方案,但如果我的想法值得的话,它只适用于2D数组。然而,这4个嵌套循环不会破坏代码的复杂性吗
List<List<Integer>> grid2 = grid1;
boolean received= false;
int hours=0;
int rows_Temp = 0 ;
int columsTemp = 0 ;
int[][] grid2 = null ;
while(rows_Temp<rows&&!received)
{
if(rows_Temp==rows-1)
{
rows_Temp=0;
}
if(rows_Temp==0)
{
//create an array with the grid dimention
grid2= new int[rows][columns];
}
//manage top left corner
if(rows_Temp==0 && columsTemp == 0 )
{
//find right & down
int center= grid.get(rows_Temp).get(columsTemp);
int right = grid.get(rows_Temp).get(columsTemp+1);
int down = grid.get(rows_Temp+1).get(columsTemp);
if(center==1)
{
if(right==0)
{
grid2[rows_Temp][columsTemp+1] = 1;
}
if(down==0)
{
grid2[rows_Temp+1][columsTemp]=1;
}
}
}
//manage top right corner
else if(rows_Temp==0 && columsTemp == columns-1)
{
//find left and down
int center= grid.get(rows_Temp).get(columsTemp);
int left = grid.get(rows_Temp).get(columsTemp-1);
int down = grid.get(rows_Temp+1).get(columsTemp);
if(center==1)
{
if(left==0)
{
grid2[rows_Temp][columsTemp-1] = 1;
}
if(down==0)
{
grid2[rows_Temp+1][columsTemp]=1;
}
}
}
//mange down left corner of the array
else if(rows_Temp==rows-1 && columsTemp == 0)
{
//find up and right
int center= grid.get(rows_Temp).get(columsTemp);
int right = grid.get(rows_Temp).get(columsTemp+1);
int up = grid.get(rows_Temp-1).get(columsTemp);
if(center==1)
{
if(right==0)
{
grid2[rows_Temp][columsTemp+1] = 1;
}
if(up==0)
{
grid2[rows_Temp-1][columsTemp]=1;
}
}
}
//manage down right corner
else if(rows_Temp==rows-1 && columsTemp == columns-1)
{
//find left and up
int center= grid.get(rows_Temp).get(columsTemp);
int left = grid.get(rows_Temp).get(columsTemp-1);
int up = grid.get(rows_Temp-1).get(columsTemp);
if(center==1)
{
if(left==0)
{
grid2[rows_Temp][columsTemp-1] = 1;
}
if(up==0)
{
grid2[rows_Temp-1][columsTemp]=1;
}
}
}
//manage left sides but not corners
else if(rows_Temp!=0&& rows_Temp!=rows-1&& columsTemp==0)
{
int center= grid.get(rows_Temp).get(columsTemp);
int right = grid.get(rows_Temp).get(columsTemp+1);
int up = grid.get(rows_Temp-1).get(columsTemp);
int down = grid.get(rows_Temp+1).get(columsTemp);
if(center==1)
{
if(right==0)
{
grid2[rows_Temp][columsTemp+1] = 1;
}
if(up==0)
{
grid2[rows_Temp-1][columsTemp]=1;
}
if(down==0)
{
grid2[rows_Temp+1][columsTemp]=1;
}
}
}
if(columsTemp==columns-1)
{
columsTemp=0;
rows_Temp++;
System.out.println();
}
else
{
columsTemp++;
}
}
System.out.println("------------");
return 0 ;
}
List grid2=grid1;
布尔值=假;
整小时=0;
int rows_Temp=0;
int columnstemp=0;
int[][]grid2=null;
while(rows_Temp如果允许更新grid
,请使用grid.get(y).get(x)
检查网格,并使用grid.get(y).set(x,value)
更新网格。如果不允许更新网格,请先将值复制到int[][]
2D数组中,然后在下面的解决方案中使用该数组
扫描网格中的0
值,并将坐标添加到队列中,例如ArrayDeque
,其中点是一个具有两个int
字段的对象,例如类
我们这样做是为了确保良好的性能,运行时复杂性为O(nm),其中n
和m
是网格的宽度和高度
以i=1
开始一个循环。在循环中,迭代队列。如果该点的相邻值等于i
,则将该点的值设置为i+1
,否则将该点添加到第二个队列中。最后,将第一个队列替换为第二个队列,将i
增加1,然后再次执行该操作,直到队列处于emp状态泰
结果是2D矩阵的级数如下所示:
0 1 1 0 1 → 2 1 1 2 1 → 2 1 1 2 1 → 2 1 1 2 1
0 1 0 0 0 → 2 1 2 0 2 → 2 1 2 3 2 → 2 1 2 3 2
0 0 0 0 1 → 0 2 0 2 1 → 3 2 3 2 1 → 3 2 3 2 1
0 0 0 1 0 → 0 0 2 1 2 → 0 3 2 1 2 → 4 3 2 1 2
矩阵中的最高值为4,因此答案为3小时,比最高值少1小时
更新
下面是代码,它将输入复制到二维数组,并将值降低1,因为这样更有意义
static int hours(int rows, int columns, List<List<Integer>> grid) {
// Build hourGrid, where value is the number of hours until the
// node can send, with MAX_VALUE meaning the node cannot send.
// Also build queue of nodes that cannot send.
int[][] hourGrid = new int[rows][columns];
Queue<Point> pending = new ArrayDeque<>();
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
if (grid.get(y).get(x) == 0) {
hourGrid[y][x] = Integer.MAX_VALUE;
pending.add(new Point(x, y));
}
}
}
// Keep iterating the queue until all pending nodes can send.
// Each iteration adds 1 hour to the total time.
int hours = 0;
for (; ! pending.isEmpty(); hours++) {
// Check all pending nodes if they can receive data
Queue<Point> notYet = new ArrayDeque<>();
for (Point p : pending) {
if ((p.x > 0 && hourGrid[p.y][p.x - 1] <= hours)
|| (p.x < columns - 1 && hourGrid[p.y][p.x + 1] <= hours)
|| (p.y > 0 && hourGrid[p.y - 1][p.x] <= hours)
|| (p.y < rows - 1 && hourGrid[p.y + 1][p.x] <= hours)) {
// Node can receive from a neighbor, so will be able to send in 1 hour
hourGrid[p.y][p.x] = hours + 1;
} else {
// Not receiving yet, so add to queue for next round
notYet.add(p);
}
}
pending = notYet;
}
return hours;
}
试验
输出
2
3.
这似乎奏效了
List<List<Integer>> grid =
new ArrayList<>(List.of(
new ArrayList<>(List.of(0, 1, 1, 0, 1)),
new ArrayList<>(List.of( 0, 1, 0, 1, 0)),
new ArrayList<>(List.of( 0, 0, 0, 0, 1)),
new ArrayList<>(List.of( 0, 1, 0, 0, 0))));
int total =0;
while (hours(4,4,grid) > 0) {
total++;
}
System.out.println(total + " hours");
}
public static void display(List<List<?>> grid) {
for (List<?> row : grid) {
System.out.println(row);
}
System.out.println();
}
public static int hours(int rows, int cols, List<List<Integer>> grid) {
int count = 0;
// count the remaining 0's and change
// the new guys to 1.
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid.get(r).get(c) == 0) {
count++;
}
if (grid.get(r).get(c) == -2) {
grid.get(r).set(c, 1);
}
}
}
if (count == 0) {
return 0;
}
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid.get(r).get(c) == 1 && grid.get(r).get(c) != -2) {
if (r + 1 < rows) {
if (grid.get(r + 1).get(c) == 0) {
grid.get(r + 1).set(c, -2);
}
}
if (r - 1 >= 0) {
if (grid.get(r - 1).get(c) == 0) {
grid.get(r - 1).set(c, -2);
}
}
if (c + 1 < cols) {
if (grid.get(r).get(c + 1) == 0) {
grid.get(r).set(c + 1, -2);
}
}
if (c - 1 >= 0) {
if (grid.get(r).get(c - 1) == 0) {
grid.get(r).set(c - 1, -2);
}
}
}
}
}
return count;
}
}
列表网格=
新建ArrayList(列表中的(
新的ArrayList(列表(0,1,1,0,1)),
新的ArrayList(列表(0,1,0,1,0)),
新的ArrayList(列表(0,0,0,0,1)),
新的数组列表(0,1,0,0,0的列表);
int-total=0;
而(小时数(4,4,网格)>0){
总计++;
}
系统输出打印项次(总+小时);
}
公共静态无效显示(列表行:网格){
系统输出打印项次(行);
}
System.out.println();
}
公共静态整数小时(整数行、整数列、列表网格){
整数计数=0;
//计算剩余的0并进行更改
//新来的家伙们到1号。
对于(int r=0;r=0){
if(grid.get(r-1).get(c)==0){
grid.get(r-1).set(c,-2);
}
}
if(c+1=0){
if(grid.get(r).get(c-1)==0){
grid.get(r.set)(c-1,-2);
}
}
}
}
}
返回计数;
}
}
根据您的示例,我假设对角邻域不计算在内。是的,仅向上/向下/向右/向左您应该从最初的1开始进行广度优先搜索。遍历所有单元格所需的层数是填充矩阵所需的小时数。好的,谢谢,我将搜索算法,但在此之前将检查surrounding top/down/left-right,并且能够将0改为1??不确定我是否已经告诉了您所述的问题……但是我在问题中写的第二次迭代发生在第一个小时的末尾……典型测试用例的解决方案将是2小时,因为第三次迭代将把所有的问题都变成一个。我完全理解这一点fo grid.get(y).set(x,value)我正在搜索它。我的解决方案中唯一的问题是,在整个迭代结束之前,您将无法编辑主网格。换句话说,当一个具有1的节点更改邻居时,它只会影响它们
static int hours(int rows, int columns, List<List<Integer>> grid) {
// Build hourGrid, where value is the number of hours until the
// node can send, with MAX_VALUE meaning the node cannot send.
// Also build queue of nodes that cannot send.
int[][] hourGrid = new int[rows][columns];
Queue<Point> pending = new ArrayDeque<>();
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
if (grid.get(y).get(x) == 0) {
hourGrid[y][x] = Integer.MAX_VALUE;
pending.add(new Point(x, y));
}
}
}
// Keep iterating the queue until all pending nodes can send.
// Each iteration adds 1 hour to the total time.
int hours = 0;
for (; ! pending.isEmpty(); hours++) {
// Check all pending nodes if they can receive data
Queue<Point> notYet = new ArrayDeque<>();
for (Point p : pending) {
if ((p.x > 0 && hourGrid[p.y][p.x - 1] <= hours)
|| (p.x < columns - 1 && hourGrid[p.y][p.x + 1] <= hours)
|| (p.y > 0 && hourGrid[p.y - 1][p.x] <= hours)
|| (p.y < rows - 1 && hourGrid[p.y + 1][p.x] <= hours)) {
// Node can receive from a neighbor, so will be able to send in 1 hour
hourGrid[p.y][p.x] = hours + 1;
} else {
// Not receiving yet, so add to queue for next round
notYet.add(p);
}
}
pending = notYet;
}
return hours;
}
static int hours(int[][] grid) {
final int rows = grid.length;
final int columns = grid[0].length;
List<List<Integer>> gridList = new ArrayList<>(rows);
for (int[] row : grid) {
List<Integer> rowList = new ArrayList<>(columns);
for (int value : row)
rowList.add(value); // autoboxes
gridList.add(rowList);
}
return hours(rows, columns, gridList);
}
System.out.println(hours(new int[][] { // data from question
{ 0, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 0 },
}));
System.out.println(hours(new int[][] { // data from answer
{ 0, 1, 1, 0, 1 },
{ 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 1, 0 },
}));
List<List<Integer>> grid =
new ArrayList<>(List.of(
new ArrayList<>(List.of(0, 1, 1, 0, 1)),
new ArrayList<>(List.of( 0, 1, 0, 1, 0)),
new ArrayList<>(List.of( 0, 0, 0, 0, 1)),
new ArrayList<>(List.of( 0, 1, 0, 0, 0))));
int total =0;
while (hours(4,4,grid) > 0) {
total++;
}
System.out.println(total + " hours");
}
public static void display(List<List<?>> grid) {
for (List<?> row : grid) {
System.out.println(row);
}
System.out.println();
}
public static int hours(int rows, int cols, List<List<Integer>> grid) {
int count = 0;
// count the remaining 0's and change
// the new guys to 1.
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid.get(r).get(c) == 0) {
count++;
}
if (grid.get(r).get(c) == -2) {
grid.get(r).set(c, 1);
}
}
}
if (count == 0) {
return 0;
}
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid.get(r).get(c) == 1 && grid.get(r).get(c) != -2) {
if (r + 1 < rows) {
if (grid.get(r + 1).get(c) == 0) {
grid.get(r + 1).set(c, -2);
}
}
if (r - 1 >= 0) {
if (grid.get(r - 1).get(c) == 0) {
grid.get(r - 1).set(c, -2);
}
}
if (c + 1 < cols) {
if (grid.get(r).get(c + 1) == 0) {
grid.get(r).set(c + 1, -2);
}
}
if (c - 1 >= 0) {
if (grid.get(r).get(c - 1) == 0) {
grid.get(r).set(c - 1, -2);
}
}
}
}
}
return count;
}
}