使用Java 8 IntStream的沙漏求和

时间:2018-12-27 19:09:01

标签: java arrays java-8

我正在尝试解决Maximum sum of hour glass in matrix

  

给出2D矩阵,任务是找到一个沙漏的最大和。

     

一个沙漏由7个电池组成   格式如下。

A B C
  D
E F G

我的实现出现问题,并且我得到了奇怪的答案。我应该得到19,但返回36。

这是我的代码:

static int hourglassSums(int[][] arr)
{
    return IntStream.range(0, 4).map(x -> {
        return IntStream.range(0, 4).map(y ->
                  arr[y][x] + arr[y][x + 1] + arr[y][x + 2] 
                  + arr[y + 1][x + 1] 
                  + arr[y + 2][x] + arr[y + 2][x + 1] + arr[y + 2][x + 2]
        ).sum();
    }).max().getAsInt();
}

public static void main(String[] args) 
{
    System.out.println("Max sum :: " + hourglassSums(new int[][] {
                    {1, 1, 1, 0, 0, 0},
                    {0, 1, 0, 0, 0, 0},
                    {1, 1, 1, 0, 0, 0},
                    {0, 0, 2, 4, 4, 0},
                    {0, 0, 0, 2, 0, 0},
                    {0, 0, 1, 2, 4, 0}
    }));
}

2 个答案:

答案 0 :(得分:4)

您已经在计算内部map通话中每个沙漏的时间总数。因此,将sum()终端操作应用于内部IntStream毫无意义,因为它增加了多个沙漏的总和。

您的代码实际上返回38,这是以下沙漏的总和:

hour      hour
glass     glass
          sum

1 0 0
  0          2
1 0 0

0 0 0
  0         10
2 4 4

1 0 0        
  4          7
0 2 0

2 4 4 
  2         19
1 2 4
            --
            38

您可以通过找到内部IntStream的最大总和,然后找到外部IntStream的最大总和来解决此问题:

static int hourglassSums(int[][] arr) {
      return IntStream.range(0, 4).map(x -> {
          return IntStream.range(0, 4).map(y ->
                  arr[y][x] + arr[y][x + 1] + arr[y][x + 2] 
                  + arr[y + 1][x + 1] 
                  + arr[y + 2][x] + arr[y + 2][x + 1] + arr[y + 2][x + 2]
          ).max().getAsInt(); // find the max hour glass sum of all the hour
                              // glasses starting at column x
      }).max().getAsInt(); // find the overall max hour glass sum
}

这将导致

Max sum :: 19

更好的选择是使用flatMap

static int hourglassSums(int[][] arr) {
      return IntStream.range(0, 4)
                      .flatMap(x -> IntStream.range(0, 4)
                                             .map(y -> arr[y][x] +
                                                       arr[y][x + 1] +
                                                       arr[y][x + 2] +
                                                       arr[y + 1][x + 1] +
                                                       arr[y + 2][x] +
                                                       arr[y + 2][x + 1] +
                                                       arr[y + 2][x + 2]))
                      .max()
                      .getAsInt();
}

通过这种方式,您可以创建所有沙漏总和的IntStream并找到该流的最大值。

答案 1 :(得分:0)

问题是您要迭代4次(0 - 3),但是沙漏在最大范围内只能是3个数字。您只需要重复3次(0-2):

static int hourglassSums(int[][] arr) {
    return IntStream.range(0, 3).map(x -> {
        return IntStream.range(0, 3).map(y ->
                arr[y][x] + arr[y][x + 1] + arr[y][x + 2] 
                + arr[y + 1][x + 1] 
                + arr[y + 2][x] + arr[y + 2][x + 1] + arr[y + 2][x + 2]
        ).sum();
    }).max().getAsInt();
}

输出:

19

哪个来自沙漏:

2, 4, 4, 
   2, 
1, 2, 4