Get max subsum from an array

2019-04-15 20:12发布

I had this question on a test recently and don't understand at all what the question is asking for, especially based on the examples:

max_subsum

Write a method, max_subsum(numbers), which takes an array and returns the start and end indices of the consecutive range which has the largest sum.

max_subsum([100, -101, 200, -3, 1000]) == [2, 4]

max_subsum([1, 2, 3]) == [0, 2]

Hints: iterate through all the subarrays; compute the sum of each subarray and compare to the max subsum seen so far. A subarray is defined by its start index and end indices, so iterate through all pairs of indices. You should probably use two loops, one nested inside the other.

I don't see any subarrays in the examples. The output from the examples simply shows the indices of smallest and largest values in the array. If that's what the question is asking for, then what summation of subarrays is happening. I must be missing something simple, I just don't know what that is. Does someone else see it?

3条回答
我只想做你的唯一
2楼-- · 2019-04-15 20:16

Here's my quick solution to your problem =)

Split the calls in order to understand what I'm doing =)

def max_subsum(a)
    (0...a.length).flat_map { |i| (i...a.length).map { |j| i..j } }.inject([a[0], 0..0]) { |max, i| a[i].inject(:+) > max.first ? [a[i].inject(:+),i ]: max }.last
end

Output:

max_subsum([100, -101, 200, -3, 1000])
=> 2..4
max_subsum([1, 2, 3])
=> 0..2

You can convert to array.. I did not bother as I like the range =)

A dynamic programming solution to this problem would be more efficient but I think you are expected to provide something along the lines of what I did during an exam :-)

Explanation:

(0...a.length).flat_map { |i| (i...a.length).map { |j| i..j } }

returns to me all the possible consecutive positions in the array. You can consider this your nested loops.

I'm then injecting the value [a[0], 0..0] and assuming it's the solution: a[0] being the max value and 0..0 being the start to end index. Inside inject, I'm comparing the max to the sum of the current slice of the array from flat_map, if it's bigger, I return the slice and the max.

查看更多
我命由我不由天
4楼-- · 2019-04-15 20:19

These are the first array's subarrays along with their sums:

[100].inject(:+)                       #=>   100
[100, -101].inject(:+)                 #=>    -1
[100, -101, 200].inject(:+)            #=>   199
[100, -101, 200, -3].inject(:+)        #=>   196
[100, -101, 200, -3, 1000].inject(:+)  #=>  1196
     [-101].inject(:+)                 #=>  -101
     [-101, 200].inject(:+)            #=>    99
     [-101, 200, -3].inject(:+)        #=>    96
     [-101, 200, -3, 1000].inject(:+)  #=>  1096
           [200, -3, 1000].inject(:+)  #=>  1197
                [-3, 1000].inject(:+)  #=>   997
                    [1000].inject(:+)  #=>  1000

[200, -3, 1000] has the largest sum

查看更多
登录 后发表回答