次のことを行うアルゴリズムを考え出す必要があります。
正の数の配列 (例: [1,3,7,0,0,9]
) があり、それらの合計が 20 であることを事前に知っているとします。
新しい合計が 7 未満になるように、各数値から平均金額を抽出します。
そのためには、次の規則に従う必要があります。
- 整数のみを減算できます
- 結果の配列に負の値があってはなりません
- バケットのインデックスを変更することはできません。
減算が配列全体に均一に分散されるほど、より良い結果が得られます。
JavaScript +アンダースコア(おそらくn ^ 2になります)のアルゴリズムでの私の試みは次のとおりです。
function distributeSubtraction(array, goal){
var sum = _.reduce(arr, function(x, y) { return x + y; }, 0);
if(goal < sum){
while(goal < sum && goal > 0){
var less = ~~(goal / _.filter(arr, _.identity).length); //length of array without 0s
arr = _.map(arr, function(val){
if(less > 0){
return (less < val) ? val - less : val; //not ideal, im skipping some!
} else {
if(goal > 0){ //again not ideal. giving preference to start of array
if(val > 0) {
goal--;
return val - 1;
}
} else {
return val;
}
}
});
if(goal > 0){
var newSum = _.reduce(arr, function(x, y) { return x + y; }, 0);
goal -= sum - newSum;
sum = newSum;
} else {
return arr;
}
}
} else if(goal == sum) {
return _.map(arr, function(){ return 0; });
} else {
return arr;
}
}
var goal = 7;
var arr = [1,3,7,0,0,9];
var newArray = distributeSubtraction(arr, goal);
//returned: [0, 1, 5, 0, 0, 7];
まあ、それはうまくいきますが、もっと良い方法があるはずです! より大きな配列とより大きな数では、このことの実行時間はひどいものになると思います。
編集: この質問は純粋に学術的なものであることを明確にしたいと思います。何かをホワイトボードに載せると、インタビュアーがアルゴリズムが異なるタイプのデータセットでどのように動作するかを尋ねるインタビューの質問のようなものだと考えてください。