はじめに
今回扱ってみる問題はこんな感じ。
n個の配列Aと整数kが入力として与えられたとき,Aの2つの要素の和がkとなる組み合わせを列挙せよ
例.
入力:A = {1, 6, 4, 5, 3},k = 7
出力:(6, 1), (3, 4)
解き方
まずは2重ループを使った全探索の方法が思いつきましたが、計算量はと性能は良さそうではありません。
少し工夫をしてみると、辞書(ハッシュテーブル)を活用することで計算量にまで減らすことができます。
/// <summary> /// 2つの要素の和がsumになる組み合わせ /// </summary> public static IEnumerable<IEnumerable<int>> FindPairs(IReadOnlyList<int> nums, int sum) { var dic = new Dictionary<int, bool>(); for (int i = 0; i < nums.Count; i++) { var current = nums[i]; var couterpart = sum - current; if (dic.ContainsKey(couterpart)) yield return new int[] { current, couterpart }; else dic[current] = true; } }
使い方
ちゃんと動作するか簡単なテストをしてみましょう。
static void Main(string[] args) { var a = new int[] { 1, 6, 4, 5, 3 }; foreach (var item in FindPairs(a, 7)) Console.WriteLine(string.Join(", ", item)); // (6, 1), (3, 4) }
さいごに
かなり部分和問題に似た問題のような気がしますが、動的計画法を用いても(bは和sum
の値)までしか計算量を落とせませんでした。
www.hanachiru-blog.com
ただ選ぶ要素の数が2個に固定になった場合、計算量をにまで減らすことができました。
なかなかに面白い結果になったのではないかと思います。
今回はこれくらいで。
ではまた。