C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で解く「最短単語距離 III」— 効率的なアルゴリズムと実装例を解説

単語のリストと、word1・word2 という2つの単語が与えられたとき、リスト内におけるこれら2つの単語間の最短距離を求めるのが本問題です。注意点として、word1 と word2 が同じ単語であるケースも存在します。例として、words = ["practice", "makes", "perfect", "skill", "makes"] というリストを考えてみましょう。


このとき、入力が word1 = "makes"、word2 = "skill" であれば、出力は 1 となります。

解法のアプローチ

この問題は、リストを先頭から一度走査しながら、各単語の最新の出現位置を記録していくことで、線形時間で効率よく解くことができます。具体的な手順は以下の通りです。

  • ret := 10^9、l1 := 10^9、l2 := -10^9 で初期化します。

  • n := words のサイズとします。

  • i := 0 から i < n の間、i を1ずつ増やしながら以下を繰り返します。

    • words[i] が word1 と一致する場合 → l1 := i と更新します。

    • words[i] が word2 と一致する場合 → word1 と word2 が同一であれば、まず l1 := l2 としたうえで、l2 := i と更新します。

    • ret := min(|l2 − l1|, ret) として、これまでの最小距離を更新します。

  • ループ終了後、ret を返します。

word1 と word2 が同じ場合に l1 := l2 を代入しているのは、直前の出現位置を保持するためです。これにより、同一単語同士の距離も正しく計算できるようになります。

C++ 実装例

理解を深めるために、以下の実装例を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   int shortestWordDistance(vector<string>& words, string word1, string word2) {
      int ret = 1e9;
      int l1 = 1e9;
      int l2 = -1e9;
      int n = words.size();
      for (int i = 0; i < n; i++) {
         if (words[i] == word1) {
            l1 = i;
         }
         if (words[i] == word2) {
            if (word1 == word2) {
               l1 = l2;
            }
            l2 = i;
         }
         ret = min(abs(l2 - l1), ret);
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<string> v = {"practice", "makes", "perfect", "skill", "makes"};
   cout << (ob.shortestWordDistance(v, "makes", "skill"));
}

入力

{"practice", "makes", "perfect", "skill", "makes"}, "makes", "skill"

出力

1

計算量

  • 時間計算量:O(n) — リスト全体を一度だけ走査します。

  • 空間計算量:O(1) — 定数個の変数のみを使用します。

  1. C++で解く「醜い数 III」:二分探索と包除原理による効率的な求め方

    n番目の「醜い数(Ugly Number)」を求めるプログラムを書くことを考えます。醜い数とは、与えられた整数 a、b、c のいずれかで割り切れる正の整数のことです。 例として、n = 3、a = 2、b = 3、c = 5 の場合を見てみましょう。このとき醜い数は小さい順に [2, 3, 4, 5, 6, 8, 9, 10, …] と並び、3番目の値は 4 となるため、出力は 4 になります。 解法のポイント:二分探索と包除原理 醜い数を順番に生成していくのは非効率です。そこで「ある値 x 以下に醜い数がいくつあるか」を高速に数える手法を使います。 x 以下の醜い数の個数は、次の包除原理によ

  2. C++でターゲットの色までの最短距離を求めるアルゴリズムを解説

    問題の概要1、2、3の3種類の色が格納された配列colorsがあるとします。いくつかのクエリが与えられ、各クエリは2つの整数iとcから構成されます。このとき、指定されたインデックスiからターゲットの色cまでの最短距離を求める必要があります。該当する色が存在しない場合は-1を返します。例えば、colors配列が[1,1,2,1,3,2,2,3,3]、queries配列が[[1,3],[2,2],[6,1]]である場合、出力は[3,0,3]となります。その理由は以下の通りです。インデックス1から最も近い「3」はインデックス4に存在するため、距離は3インデックス2から最も近い「2」はインデックス2自