【问题标题】:Hourglass sum in 2D array二维数组中的沙漏和
【发布时间】:2016-10-27 10:54:59
【问题描述】:

给定一个 (6*6) 二维数组,我们必须在其中找到一个沙漏的最大和。 例如,如果我们在一个全零的数组中使用数字 1 创建一个沙漏,它可能看起来像这样:

沙漏的总和是其中所有数字的总和。上面沙漏的总和分别是 7、4 和 2。

我为它编写了如下代码。这基本上是一个有竞争力的编程问题,由于我是该领域的新手,我编写的代码的复杂性非常糟糕。也许程序无法生成在规定的时间内所需的输出。下面是我的代码:

    int main(){
    vector< vector<int> > arr(6,vector<int>(6));
    for(int arr_i = 0;arr_i < 6;arr_i++)
    {
      for(int arr_j = 0;arr_j < 6;arr_j++)
       {
        cin >> arr[arr_i][arr_j];
       }
    } //numbers input

    int temp; //temporary sum storing variable
    int sum=INT_MIN; //largest sum storing variable
    for(int i=0;i+2<6;i++) //check if at least3 exist at bottom
     { 
       int c=0; //starting point of traversing column wise for row

       while(c+2<6) //three columns exist ahead from index
        {  
          int f=0; //test case variable
          while(f!=1)  
          { //if array does not meet requirements,no need of more execution  

            for(int j=c;j<=j+2;j++)
             { //1st and 3rd row middle element is 0 and 2nd row is non 0.
               //condition for hourglass stucture                    
             if((j-c)%2==0 && arr[i+1][j]==0||((j-c)%2==1 && arr[i+1][j]!=0)
             //storing 3 dimensional subarray sum column wise               
             temp+=arr[i][j]+arr[i+1][j]+arr[i+2][j]; //sum storage 
             else
             f=1; //end traversing further on failure


              if(sum<temp)
              sum=temp;

              f=1;//exit condition
              }//whiel loop of test variable 

             temp=0; //reset for next subarray execution
             c++; /*begin traversal from one index greater column wise till 
                    condition*/
              }// while loop of c
        } 
      }       

          cout<<sum;

         return 0;
    }

这是我在时间间隔内无法处理的代码的实现。考虑到时间复杂度,请提出一个更好的解决方案,并随时指出我在理解问题方面的任何错误。问题来自 Hackerrank。 如果您仍然需要,这里是链接: https://www.hackerrank.com/challenges/2d-array

【问题讨论】:

  • 令人惊讶的是,图片链接不起作用。请参阅底部的链接以了解完整的问题。
  • 如果您的代码已经在工作,您可能会更幸运地在 codereview.stackexchange.com 上发布此内容。
  • 你测试过它的一些输入吗?
  • 在 6x6 数组上循环不会花费很长时间 - 我怀疑您的代码中某处存在无限循环。 whiles 特别可疑 - 对于一个简单的算法,您最多需要两个 fors。
  • //1st and 3rd row middle element is 0 and 2nd row is non 0. 是什么意思?

标签: c++ arrays multidimensional-array


【解决方案1】:

您的问题的解决方案是:

#include <cstdio>
#include <iostream>
#include <climits>

int main() {
    int m[6][6];

    // Read 2D Matrix-Array
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 6; ++j) {
            std:: cin >> m[i][j];
        }
    }

    // Compute the sum of hourglasses
    long temp_sum = 0, MaxSum = LONG_MIN;
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 6; ++j) {
            if (j + 2 < 6 && i + 2 < 6) {
                temp_sum = m[i][j] + m[i][j + 1] + m[i][j + 2] + m[i + 1][j + 1] + m[i + 2][j] + m[i + 2][j + 1] + m[i + 2][j + 2];
                if (temp_sum >= MaxSum) {
                    MaxSum = temp_sum;
                }
            }
        }
    }
    fprintf(stderr, "Max Sum: %ld\n", MaxSum);

    return 0;
}

算法很简单,将左上角开始的所有沙漏相加,最后2列和2行不处理,因为它不能形成沙漏。

【讨论】:

  • 这确实是一种更好、更简洁的解决问题的方法。感谢您的时间和努力。
  • 当然可以,但是我对代码进行了轻微修改,以使其适用于所有可能的测试用例。请检查一次。
  • 为什么要有额外的 if 条件,如果我们从 1 循环到 5 并相应地调整索引,则可以不用它来解决
  • @mohit 从 0 到 4,不是吗?
【解决方案2】:

上面的代码几乎是正确的,但它不适用于负数组元素。我们不应该将最大总和视为 0,因为负数数组可能无法达到它们的最大总和 >=0。在这种情况下,将 max sum 初始化为 INT_MIN 是一个更好的选择。

【讨论】:

  • 你能解释一下你的答案吗?
【解决方案3】:

我已经在 Python 3.0 中解决并通过了 HackerRank 中的所有测试用例: 想法:只需 3 个简单的步骤:

  1. 提取 6X6 矩阵中的所有 16 个 3X3。获取每个子矩阵和 Find 所有子矩阵和的最大值

我已将负值的最大值初始化为 -1000,您也可以使用 Minimum_Integer 值对其进行初始化

 # Complete the hourglassSum function below.
    def hourglassSum(arr):
        max = -1000
        s= []
        sub_array = []
        for m in range(4)://Move vertically down the rows like(012,123,234,345 and taking 3 values horizontally)
            for col in range(4):
                for row in range(3):
                    sub_array.append(arr[row+m][col:col+3])
                    s = sub_array//Extracting all 16 3X3 matrices
                hour_sum = sum_list(s[0])+s[1][1]+sum_list(s[2])//Mask array for hour_glass index[[1,1,1],[0,1,1],[1,1,1]]
                if (max<hour_sum):
                    max = hour_sum
                sub_array = []
        return max

    def sum_list(list1):
        total = 0
        for ele in range(0, len(list1)):
            total = total + list1[ele]
        return total

""" 额外:尝试在您的 Spyder 中将其替换为更少的代码行 而不是

现有:没有 numpy

hour_sum = sum_list(s[0])+s[1][1]+sum_list(s[2])//Mask array for hour_glass index[[1,1,1],[0,1,1],[1,1,1]]
        if (max<hour_sum):
           max = hour_sum

使用 numpy:

import numpy as np
import numpy.ma as ma
    hour_glass = ma.array(sub_array, mask=mask)
            sum = hour_glass.data.sum()

"""

【讨论】:

    【解决方案4】:

    这是这个算法的python实现。

    arr = []
    
    for _ in xrange(6):
        arr.append(map(int, raw_input().rstrip().split()))
    
    maxSum = -99999999
    for row in range(len(arr)):
        tempSum = 0
        for col in range(len(arr[row])):
            if col+2 >= len(arr[row]) or row+2 >= len(arr[col]):
                continue
            tempSum = arr[row][col] + arr[row][col+1] + arr[row][col+2] + arr[row+1][col+1] + arr[row+2][col] + arr[row+2][col+1] + arr[row+2][col+2]
            if maxSum < tempSum:
                maxSum = tempSum
    print(maxSum)
    

    【讨论】:

      【解决方案5】:

      Swift 4 版本:

      func hourglassSum(arr matrix: [[Int]]) -> Int {
            let h = matrix.count
            if h < 3 {
               return 0
            }
            let w = matrix[0].count
            if w < 3 {
               return 0
            }
            var maxSum: Int?
      
            for i in 0 ..< h - 2 {
               for j in 0 ..< w - 2 {
                  // Considering matrix[i][j] as top left cell of hour glass.
                  let sum = matrix[i][j] + matrix[i][j+1] + matrix[i][j+2]
                     + matrix[i+1][j+1]
                     + matrix[i+2][j] + matrix[i+2][j+1] + matrix[i+2][j+2]
                  // If previous sum is less then current sum then update new sum in maxSum
                  if let maxValue = maxSum {
                     maxSum = max(maxValue, sum)
                  } else {
                     maxSum = sum
                  }
               }
            }
            return maxSum ?? 0
      }
      

      【讨论】:

        【解决方案6】:

        只是避免了四次 for 循环迭代

         int main()
        {
         int arr[6][6],max=-1,sum;
        for(int arr_i = 0; arr_i < 6; arr_i++){
           for(int arr_j = 0; arr_j < 6; arr_j++){
        
              scanf("%d",&arr[arr_i][arr_j]);
               if(arr[arr_i][arr_j]<-9||arr[arr_i][arr_j]>9)
                   exit(0);
           }
        }
         for(int arr_i = 0; arr_i <4; arr_i++)
         {
             sum=0;
           for(int arr_j = 0; arr_j < 4; arr_j++){
                sum=arr[arr_i][arr_j]+arr[arr_i][arr_j+1]+arr[arr_i][arr_j+2]+arr[arr_i+1][arr_j+1]+arr[arr_i+2][arr_j]+arr[arr_i+2][arr_j+1]+arr[arr_i+2][arr_j+2];
               if(sum>max)
                max=sum;
        
        
           }
        }
        printf("%d",max);
        return 0;
        

        }

        【讨论】:

        • 你想在这里实现什么?如果您认为自己提供了有用的答案,那么一些解释可能会有所帮助。
        【解决方案7】:
         int main(){
            vector< vector<int> > arr(6,vector<int>(6));
            for(int arr_i = 0;arr_i < 6;arr_i++){
               for(int arr_j = 0;arr_j < 6;arr_j++){
                  cin >> arr[arr_i][arr_j];
               }
            }
        
            int sum=-100, temp;
            for(int arr_i = 0;arr_i < 4;arr_i++){
               for(int arr_j = 0;arr_j < 4;arr_j++){
                   temp=(arr[arr_i][arr_j]+arr[arr_i][arr_j+1]+arr[arr_i][arr_j+2]+arr[arr_i+1][arr_j+1]+arr[arr_i+2][arr_j]+arr[arr_i+2][arr_j+1]+arr[arr_i+2][arr_j+2]);
                   if(temp>sum)
                       sum=temp;
               }
            }
            cout << sum;    
            return 0;
        }
        

        【讨论】:

        【解决方案8】:
        def hourglassSum(arr)
        maxHourGlass = -82
        counter = 0
        for i in 1..4
            for j in 1..4
                acc = arr[i][j]
                counter= counter +1
                for x in -1..1
                    acc = acc + arr[i-1][j+x] + arr[i+1][j+x]
                end
                maxHourGlass = acc if acc > maxHourGlass
            end
        end
        maxHourGlass
        end
        

        【讨论】:

          【解决方案9】:

          这是用 C++14 编写的,通过了所有九个测试用例。我认为有人可以改进它以使用更多 C++14 功能。

          int hourglassSum(vector<vector<int>> arr)
          {
              if(arr.size() < 3 || arr[0].size() < 3 )
                  return -1;
          
              int rowSize = arr[0].size();
              int sum = -9 * 6; // smallest negative sum possible;
          
              for( int i = 1; i < arr.size()-1; i++ )
              {
                  int tmp_sum = 0;
          
                  for( int j = 1; j < rowSize-1; j++ )
                  {
                      tmp_sum  = (arr[i - 1][j - 1] + arr[i - 1][j] + arr[i - 1][j + 1] );
                      tmp_sum += (arr[i    ][j    ]);
                      tmp_sum += (arr[i + 1][j - 1] + arr[i + 1][j] + arr[i + 1][j + 1]);
          
                      sum = max(tmp_sum, sum);
                  }
              }
          
              return sum;
          }
          

          【讨论】:

            【解决方案10】:
            class Solution {
            
                static void Main(string[] args) {
                    int[][] arr = new int[6][];
            
                    for (int i = 0; i < 6; i++) {
                        arr[i] = Array.ConvertAll(Console.ReadLine().Split(' '), arrTemp => Convert.ToInt32(arrTemp));
                    }
                    int[] sum=new int[16];
                    int j;
                    int count=0;
                    for(int i=0; i<4; i++)
                    {
                        for(j=0;j<4;j++)
                    {
                        if(count<16)
                        {
                       sum[count]=arr[i][j]+arr[i][j+1]+arr[i][j+2]+arr[i+1][j+1]+arr[i+2][j]+arr[i+2][j+1]+arr[i+2][j+2];
                       count++;
                        }
                    }
            
                    }
                    int max=sum.Max();
                    Console.WriteLine(max);
                }
            }
            

            【讨论】:

              【解决方案11】:

              在数组中找到的最大(最大)沙漏总和将为 -63,因为元素不能大于 -9,即 -9*7 = -63

              C#

              int max_hourglass_sum = -63;
              for (int i = 0; i <arr.Length-2; i++) { //row
                  for (int j = 0 ; j<arr.Length-2; j++) { //column
                      int current_hourglass_sum = arr[i][j] + arr[i][j+1] + arr[i][j+2]  //1st row
                          + arr[i+1][j+1] //2nd row
                          + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2] ;//3rd row
                      max_hourglass_sum = Math.Max(max_hourglass_sum , current_hourglass_sum); 
                  }
              }
              

              【讨论】:

                【解决方案12】:

                java的基本解决方案;

                
                  static int hourglassSum(int[][] arr) {
                        
                        int sum = 0;
                        
                        for(int i = 2; i<6; i++){
                            for(int j = 2; j<6; j++){
                                
                                int up = arr[i-2][j-2] + arr[i-2][j-1] + arr[i-2][j];
                                int mid = arr[i-1][j-1];
                                int down = arr[i][j-2] + arr[i][j-1] + arr[i][j];
                                
                                if(up+mid+down > sum){
                                     sum = up+mid+down;
                                }
                            }    
                        }
                        return sum;
                    }
                
                

                【讨论】:

                  【解决方案13】:
                  static int hourglassSum(int[][] arr) {
                      int result = int.MinValue;
                      int rowLength = arr.GetLength(0);
                      int colLength = arr.Length;
                      
                     for (int i = 0; i < rowLength - 2; i++)
                      {
                          for(int j=0; j< colLength - 2; j++)
                          {
                              int sum = 0;
                              sum = arr[i][j] + arr[i][j+1] + arr[i][j+2]+ arr[i+1][j+1]
                                  + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2];
                              result = Math.Max(result,sum);
                          }
                      } 
                      return result;
                  }
                  

                  【讨论】:

                    【解决方案14】:
                    def hourglassSum(arr):
                        arr_sum = -5000
                        tmp_sum = 0
                        
                        for i in range(0, 6-2):
                            for j in range (0, 6-2):
                                tmp_sum = arr[i][j] + arr[i][j+1] + arr[i][j+2] + \
                                                 + arr[i+1][j+1]  + \
                                        arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]
                          
                                if arr_sum < tmp_sum:
                                    arr_sum = tmp_sum
                        
                        return arr_sum
                        
                    

                    【讨论】:

                      【解决方案15】:

                      #JavaScript(Nodejs)

                      function hourglassSum(arr) {
                          // Write your code here
                          let count = -63;
                      
                        for(let i = 0; i <= 3; i++){
                          for(let j = 0; j <= 3; j++){
                            let sum = arr[i][j] + arr[i][j+1] + arr[i][j+2] + arr[i+1][j+1] 
                            + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]
                      
                            if(sum > count){
                              count = sum
                            }
                          }
                        }
                        return count;
                      
                      }
                      

                      【讨论】:

                      • 您是如何得出count-63 值的?
                      【解决方案16】:
                      function hourglassSum(arr) {
                          const hourGlass = [];
                          for (let i = 0; i < 4; i++) {
                              for (let x = 0; x < 4; x++) {
                                  let hourGlassSumValue = arr[i][x] + arr[i][x + 1] + arr[i][x + 2] + arr[i + 1][x + 1] + arr[i + 2]enter code here[x] + arr[i + 2][x + 1] + arr[i + 2][x + 2];
                                  hourGlass.push(hourGlassSumValue);
                              }
                          }
                          return Math.max(...hourGlass);
                      }
                      console.log(hourglassSum(cars));
                      

                      【讨论】:

                        猜你喜欢
                        • 2016-09-18
                        • 1970-01-01
                        • 1970-01-01
                        • 2022-06-17
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-01-19
                        相关资源
                        最近更新 更多