コーディング面接対策サイトCodilityの練習問題を解いてみた(MinMaxDivision)
問題
配列AをK個に分割し、それぞれ分割したブロックの和を求める。 すべての配列の要素は5以下。
A = [2, 1, 5, 1, 2, 2, 2], K = 3, M = 5 なら
[2, 1, 5, 1, 2, 2, 2], , なら、分割したブロックの和の最大値 15; [2], [1, 5, 1, 2], [2, 2] なら、分割したブロックの和の最大値 9; [2, 1, 5], [], [1, 2, 2, 2] なら、分割したブロックの和の最大値 8; [2, 1], [5, 1], [2, 2, 2] なら、分割したブロックの和の最大値 6.
それぞれのパターンで算出した分割したブロックの和の最大値の中で、最小値を求めることがgoal。
回答
K == 1 なら各要素の総和(high)に K == 配列の長さなら、各要素の中で最大のもの(low)が答えに それ以外の場合なら、lowとhighの間に答えがあるはずなので、BinarySearchで、ちょっとずつ計算する
#A = [2,1,5,1,2,2,2] def solution(k, m, a) if k == 1 return a.inject(0) {|sum, x| sum + x } elsif k == a.length return a.max else # use binary search low = a.max high = a.inject(0) {|sum, x| sum + x } while (low <= high) do mid = (low + high) / 2 p "mid = #{mid}" if check(a, k, mid) high = mid - 1 else low = mid + 1 end end return low end end def check(a, k, mid) sum = 0 blocks = 0 a.each {|e| if ( (sum + e) > mid ) sum = e blocks += 1 return false if blocks >= k else sum += e end #puts "sum = #{sum}, blocks = #{blocks}, k = #{k}, mid = #{mid} " } return true end p solution(3,5,A)