1218.最長の固定差分サブシーケンス

記事のディレクトリ

1つのトピックの理解

整数配列arrと整数の差がある場合、arrの最長の算術サブシーケンスの長さを見つけて返します。サブシーケンス内の隣接する要素間の差は、差に等しくなります。
入力:整数配列arr、整数差
出力:最長の算術サブシーケンスの長さ
ルール:この算術サブシーケンスの隣接する要素間の差は差に等しい
例1:
入力:arr = [1,2,3,4]、差= 1
出力:4
説明:最長の算術サブシーケンスは[1,2,3,4]です。

例2:
入力:arr = [1,3,5,7]、difference = 1
出力:1
説明:最長の算術サブシーケンスは任意の単一要素です。

例3:
入力:arr = [1,5,7,8,5,3,4,2,1]、difference = -2
出力:4
説明:最長の等差数列は[7,5,3,1]です。 。

2考え始める

例として、arr = [1,5,7,8,5,3,4,2,1]、difference = -2を取り上げます。
プロセス1、サブシーケンスは[1]、
プロセス5です。5-1!=-1であるため、サブシーケンス[5]が生成されます。このとき、サブシーケンスには[1]、[5]、
プロセス7があります。 -5!= -2,7-1!=-2であるため、サブシーケンス[7]が生成されます。このとき、サブシーケンスには[1]、[5]、および[7]の
ハンドル8があります。 ..、この時点で、サブシーケンスには[1]、[5]、[7]、[8]
ハンドル5があります。これは、5-8!=-2,5-7 = -2であるため、サブシーケンスは次のようになります。[ 1]、[5]、[7,5]、[8]

したがって、各番号を処理するときに、彼が以前に形成した各サブシーケンスの特定の番号と比較し、一致する場合は追加できることがわかります。条件を満たし、条件を満たさない場合は別のサブシーケンスになります。もちろん、追加するときは、最長のサブシーケンスの後に追加することを選択する必要があります。
サブシーケンスに番号が追加された場合、後続の処理はこの番号にのみ関連し、サブシーケンスの特定のシーケンスとは関係がないため、dpを使用できます。
dp [i]を使用して、arr [i]で終わる算術サブシーケンスの最長の長さを表します。最終結果では、dp [0]、dp [1] ... dp [n-1]の中から最大のものが選択されます。

class Solution {
    public int longestSubsequence(int[] arr, int difference) {
        int n = arr.length;
        int[] dp = new int[n];
        dp[0] = 1;
        int max = 1;
        for(int i=1;i<n;i++){
            dp[i] = 1;
            for(int j=0;j<i;j++){
                if(arr[j] + difference == arr[i]){
                    dp[i] = Math.max(dp[i],1+dp[j]);
                }
            }
            max = Math.max(max,dp[i]);
        }
        return max;
    }
}

送信後にタイムアウトが見つかりました。もう一度考えて。arr [i]を処理するとき、その算術サブシーケンスの前の値が決定され、それはarr [i] -differenceでなければなりません。つまり、0からi-1までの各サブシーケンスの最長の長さを気にする必要はなく、arr [i] -differenceで終わる算術サブシーケンスの長さだけを気にする必要があります。

class Solution {
    public int longestSubsequence(int[] arr, int difference) {
        int n = arr.length;
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        int[] dp = new int[n];
        dp[0] = 1;
        map.put(arr[0],1);
        int max = 1;
        for(int i=1;i<n;i++){
            dp[i] = 1;
            int t = arr[i] - difference;
            if(map.containsKey(t)){
                dp[i] = Math.max(dp[i],map.get(t)+1);
            }
            map.put(arr[i],dp[i]);
            max = Math.max(max,dp[i]);
        }
        return max;
    }
}

自分の後に315カウントの小さい数を実行するとき、繰り返される要素にマップを使用することを考慮していなかったため、間違いを犯しました。だから今私は少し躊躇しています、これはできますか?値が繰り返されるとエラーが発生しますか?

それでも上記の例:[1]、[5]、[7,5]、[8]、数値3を扱う場合、3-(-2)= 5、もちろん[7,5]の後に追加すると次のようになります。 [7,5,3]。左から右に処理します。マップの長さが5の場合、3の前に5を表示する必要がありますが、5の位置は関係ありません。サブシーケンスは必ずしも連続的ではないためです。
別の角度から考えてみましょう。arr [i-3] arr [i-1] arr [i]が等差数列の
場合、arr [j] = arr [i]であり、j> iの場合、arr [i-3] arr [i- 1] arr [j]も等差数列でなければなりません。また、iとjの間では、より長い等差数列配列が生成される場合があります。
したがって、マップの最適化では、arr [i]をキーとして問題はありません。

おすすめ

転載: blog.csdn.net/flying_all/article/details/111879061