返回

LeetCode 15:探寻三数之和的奥秘——巧思破解难题,代码助你一臂之力

前端

三数之和:揭秘算法背后的巧思

直击痛点

算法の世界には、単純に見えるものもありますが、緻密に練り込まなければ解くことができないものもあります。LeetCode 15 の「三数之和」はその好例です。この問題では、与えられた配列の中で、和が 0 になる 3 つの数字の組を見つけることが求められます。一見、複雑そうですが、適切なデータ構造とアルゴリズムを利用することで、この難題を解決できます。

アルゴリズムの剖析

三数之和問題を解くには、以下の手順を踏みます。

  1. 配列のソート: まず、配列をソートします。これにより、配列内の要素が小さい順に並び、その後のアルゴリズムに役立ちます。
  2. 2 本のポインタ法: ソート後、2 本のポインタ法を使用して 3 つの数字の組を見つけます。2 本のポインタ法とは、配列の両端から 2 つのポインタを移動させ、要素の値を比較する一般的なアルゴリズム手法です。
  3. 目標値の決定: 2 本のポインタ法の実行中、ポインタが指す 3 つの要素の和を計算し続けます。和が 0 の場合、3 つの数字の組が見つかりました。和が 0 未満の場合、左側のポインタを右に移動して和を大きくします。和が 0 より大きい場合、右側のポインタを左に移動して和を小さくします。
  4. 重複の回避: 3 つの数字の組を見つける際に、重複した組を回避する必要があります。これは、すでに発見した組を記録することで実現できます。たとえば、ハッシュ表を使用して発見した組を格納し、新しい組を探すたびにハッシュ表をチェックして重複を回避できます。

コード例

以下のコード例は、三数之和問題を解決する Python コードです。

def three_sum(nums):
  """
  :type nums: List[int]
  :rtype: List[List[int]]
  """
  # 配列をソートする
  nums.sort()

  # 結果のリストを初期化する
  result = []

  # 配列を 2 本のポインタを使用して反復処理する
  for i in range(len(nums) - 2):
    # 重複した要素をスキップする
    if i > 0 and nums[i] == nums[i - 1]:
      continue

    # 左側のポインタと右側のポインタを設定する
    left = i + 1
    right = len(nums) - 1

    # 和が 0 になる 3 つの要素を見つける
    while left < right:
      # 3 つの要素の和を計算する
      sum = nums[i] + nums[left] + nums[right]

      # 和が 0 の場合、3 つの要素を結果のリストに追加する
      if sum == 0:
        result.append([nums[i], nums[left], nums[right]])

        # 重複した要素をスキップする
        while left < right and nums[left] == nums[left + 1]:
          left += 1
        while left < right and nums[right] == nums[right - 1]:
          right -= 1

        # 左側のポインタと右側のポインタを移動する
        left += 1
        right -= 1

      # 和が 0 未満の場合、左側のポインタを右に移動する
      elif sum < 0:
        left += 1

      # 和が 0 より大きい場合、右側のポインタを左に移動する
      else:
        right -= 1

  # 結果のリストを返す
  return result

考察:思考と工夫の融合

三数之和問題は、アルゴリズムデザイナーのデータ構造とアルゴリズムに関する理解と適用能力をテストする古典的で挑戦的な問題です。2 本のポインタ法やソートされた配列などの手法を駆使することで、この難題を巧みに解決できます。アルゴリズムの世界では、思考と工夫の完璧な融合が、驚くべき成果を生み出すことがよくあります。この記事が、アルゴリズムの道のりであなたにインスピレーションを与え、さらなる飛躍へと導くことを願っています。

よくある質問(FAQ)

  • Q1: なぜ配列をソートする必要があるのでしょうか?
    • A1: ソートにより、配列内の要素が小さい順に並び、2 本のポインタ法で効率的に 3 つの数字の組を見つけることができます。
  • Q2: 2 本のポインタ法の仕組みは?
    • A2: 2 本のポインタ法は、配列の両端からポインタを移動させ、要素の値を比較するアルゴリズム手法です。和が 0 になる 3 つの要素を見つけるために使用できます。
  • Q3: 重複した 3 つの数字の組を回避する方法を教えてください。
    • A3: 発見した 3 つの数字の組を格納するハッシュ表を使用することで、重複した組を回避できます。
  • Q4: このアルゴリズムの計算量はどのくらいですか?
    • A4: このアルゴリズムの計算量は、配列の長さ n に対して O(n^2) です。
  • Q5: このアルゴリズムを他の問題に応用できますか?
    • A5: はい、このアルゴリズムは、3 つの数字の組が特定の条件を満たす必要があるような、類似の問題に応用できます。