leetcode 1218. 与えられた差分の最長部分算術シーケンス

ここに画像の説明を挿入

配列 arr と差分が与えられた場合、arr 内の数値の順序を乱すことなく最長のサブシーケンスを抽出し、シーケンス内のすべての隣接する 2 つの要素間の差分が相違となるようにします。条件を満たす最長のサブシーケンスの長さを求めます

アイデア:

DP

差分差分は固定されるため、要素を抽出するたびにその前の要素も固定されます。
たとえば、現在の要素が arr[ i ] である場合、その前の要素は arr[ i ] - 差分でなければならないため、
arr[ i ] までのシーケンス長も固定されます。

arr[ i ] までの部分列の長さをカウントするだけで済みます。
これらの長さの最大値をメモしておきます。

dp 配列は、hashMap を使用して (arr[ i ]、arr[ i ] までのサブシーケンスの長さ)、
または配列を保存できます。

(1)ハッシュマップ

    public int longestSubsequence(int[] arr, int difference) {
    
    
        Map<Integer,Integer> dp = new HashMap<>();
        int n = arr.length;
        int res = 0;

        for(int i = 0; i < n; i++) {
    
    
            dp.put(arr[i], dp.getOrDefault(arr[i]-difference, 0)+1);
            res = Math.max(res, dp.get(arr[i]));
        }

        return res;
    }

(2) 配列は
要素に直接添字を付けるので高速です
記憶領域を節約するため、dp 配列の長さは arr の最大値 - 最小値 + 1 になります。
ただし、dp の添字は arr であることに注意してください。 [ i ] - 分、および arr の添字 i ではありません。

    public int longestSubsequence(int[] arr, int difference) {
    
    
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        int res = 1;

        for(int num : arr) {
    
    
            min = Math.min(min, num);
            max = Math.max(max, num);
        }

        int[] dp = new int[max-min+1];
        for(int i = 0; i < arr.length; i++) {
    
    
            int cur = arr[i] - min;
            int pre = cur - difference;
            if(pre >= 0 && pre < dp.length) {
    
    
                dp[cur] = dp[pre] + 1;
                if(dp[cur] > res) res = dp[cur];
            } else {
    
    
                dp[cur] = 1;
            }
        }
        return res;
    }

おすすめ

転載: blog.csdn.net/level_code/article/details/131715889