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

JavaScriptで最も長い非共通部分列(LUS)を見つける方法

文字列の配列を受け取り、その中から最長非共通部分列(Longest Uncommon Subsequence)を見つけるJavaScript関数を作成する必要があります。

ここで「最長非共通部分列」とは、配列内のいずれか1つの文字列の部分列でありながら、他のどの文字列の部分列としても現れない、最長の部分列のことを指します。

この関数は、そのような最長非共通部分列の長さを返す必要があります。

問題の例

例えば、入力配列が次のようになっているとします。

const arr = ["aba", "cdc", "eae"];

この場合、出力は 3 になります。「aba」「cdc」「eae」は互いに他方の部分列ではないため、最も長い非共通部分列の長さは、これらの文字列のうち最も長いものの長さである3となるからです。

解き方のポイント

この問題を解く際の基本的な考え方は以下の通りです。

  • 各文字列が配列内に出現する回数を記録します。
  • すべての文字列が互いに異なり、どの文字列も他の文字列の部分列になっていない場合、答えは単純に最も長い文字列の長さになります。
  • 一方、ある文字列が別の文字列の部分列として含まれる場合は、その文字列は「非共通」ではないため候補から除外し、残った文字列の中で最も長いものの長さを求めます。

コード例

この問題に対する実装コードは次のようになります。

const arr = ["aba", "cdc", "eae"];
const findUncommonLength = (array = []) => {
    const seen = {};
    const arr = [];
    let max = -1;
    let index = -1;
    for(let i = 0; i < array.length; i++){
        seen[array[i]] = (seen[array[i]] || 0) + 1;
        if(seen[array[i]] > 1){
            if(max < array[i].length){
                max = array[i].length;
                index = i;
            }
        }
    };
    if(index === -1) {
        array.forEach(el => {
            if(el.length > max) max = el.length;
        });
        return max;
    };
    for(let i = 0; i < array.length; i++){
        if(seen[array[i]] === 1) arr.push(array[i]);
    };
    max = -1;
    for(let i = arr.length - 1; i >= 0; i--){
        let l = arr[i];
        let d = 0;
        for(let j = 0; j < array[index].length; j++){
            if(array[index][j] === l[d]){
                d++;
            }
        }
        if(d === l.length){
            let temp = arr[i];
            arr[i] = arr[arr.length - 1];
            arr[arr.length - 1] = temp;
            arr.pop();
        }
    };
    arr.forEach(el => {
        if(el.length > max) max = el.length;
    });
    return max;
};
console.log(findUncommonLength(arr));

コードの解説

まず、オブジェクト seen を使って各文字列の出現回数を数えています。重複する文字列が存在しない場合(index === -1 の場合)は、配列内で最も長い文字列の長さをそのまま返します。

重複が存在する場合は、一度だけ出現している文字列だけを新しい配列 arr に集めます。その後、各文字列が基準となる文字列の部分列になっているかを2ポインタ的な走査で判定し、部分列になっている要素を配列から取り除きます。最後に残った文字列の中で最大の長さを返すことで、最長非共通部分列の長さが得られます。

出力結果

上記のコードを実行すると、コンソールには次のように表示されます。

3
  1. JavaScriptで文字列内の最長連続文字とその出現回数を検索する方法

    問題文字列を受け取り、その中で最も長く連続して現れる文字とその連続回数を返すJavaScript関数を作成する必要があります。戻り値は必ず2つの要素を持つ配列とします。1つ目の要素:文字列内で最も多く連続して登場する文字2つ目の要素:その文字が連続して登場した回数解決のアプローチこの問題は、文字列を先頭から1文字ずつ走査し、隣接する文字同士を比較することで解決できます。同じ文字が続いている間はカウントを増やし、異なる文字が出現した時点でカウントをリセットします。その際、これまでに記録した最大連続回数を上回っていれば、その文字と回数を結果として保存していきます。コード例以下が実際のコードです。c

  2. JavaScriptで配列のネストされた集合の最長の長さを見つけて返す方法

    問題数値の配列 arr を第一引数(かつ唯一の引数)として受け取るJavaScript関数を作成する必要があります。長さ N の配列 arr には、0 から N-1 までのすべての整数がちょうど1回ずつ含まれています。この関数では、次のルールに従って構成される集合 S の最長の長さを見つけ、その結果を返す必要があります。ここで、S[i] = {A[i], A[A[i]], A[A[A[i]]], ...} と定義されます。具体的には、S の最初の要素としてインデックス i の要素 A[i] を選択することから始め、次の要素は A[A[i]]、その次は A[A[A[i]]]… というように順に辿