300.最長増加部分列(中)

アイデア:

前の解決策によっては、動的計画法(dp)を使用するために、シーケンス表現を不連続にすることができます。

 

 

コード:

class Solution {
    public int lengthOfLIS(int[] nums) {
		if(nums.length==0) return 0;
		int[] dp=new int[nums.length+1];
		//把所有dp置为1,因为就算所有都不符合,到最后一个的时候自身也符合
		Arrays.fill(dp,1);
                int res=0;

                
		for(int i=0;i<nums.length;i++){
			for(int j=0;j<i;j++){
				//此处的dp有不符合条件时"跳过"的功能
				//注意j是每次从头遍历一遍,不只是i-1
				//就算遍历到之前不符合条件的值也没事,dp就算+1,dp仍是前一个的值
                                //此处的if有跳过功能,若不满足,则dp[i]为1
				if(nums[i]>nums[j]){
					dp[i]=Math.max(dp[i],dp[j]+1);
				}
			}
                    //每次在第二重循环结束后都要比较一下
                    //因为不是dp[n-1]就是最大的,有可能dp[n-1]为1
                    res=Math.max(res,dp[i]);
		}
		    return res;
	}
}

 

壊す:

1)ダブルループを設定します。前に進むたびに、前から後ろに1回トラバースする必要があります。これにより、オーバーラップのサブ問題が満たされます。

for(int i=0;i<n;i++){
	for(int j=0;j<i;j++)

 

2)if判定文を設定し、jが満たされない場合にスキップする機能があります

if(nums[i]>nums[j])

 

3)コアコードは次のとおりです。

dp [i]にはキャッシュ機能があります。現在のdp [i]は、以前の最長のシーケンスを格納します。nums[i]> nums [j]の条件が満たされた場合、dp [i]とdp [j] +1を比較します。

 

dp [i]とdp [j] +1を比較します。

nums [i]> nums [j]であっても、dp [j]に現在の値を加えたものが、前に存在する最長増加部分列よりも小さい場合は、前の部分列(dp [i]によってバッファリングされます)

同時に、動的計画法の最適なサブ問題も満たします。

if(nums[i]>nums[j]){
    dp[i]=Math.max(dp[i],dp[j]+1);
}

 

4)2回目のリサイクル後、毎回比較します。どちらかのdp [n-1]が最大であるため、dp [n-1]が1(動的計画法の詳細ピット)である可能性があります。

res=Math.max(res,dp[i])

 

5)添え字のオーバーフローを防ぐために、dpが宣言されると、長さはnに基づいて1(n + 1)加算されます。

 

6)それは2番目のdp形式属します現在の値は以前に計算されたすべての値に依存します

おすすめ

転載: blog.csdn.net/di_ko/article/details/115228290