スライディングウィンドウの問題--- 2ポインターソリューション

スライディングウィンドウの問題:

スライドウィンドウなどの問題は、通常、文字列と配列に基づくダブルポインタを使用して解決する必要があります。

  1. 長い文字列と短い文字列の2つの文字列を指定し、短い文字列が長い文字列の特定の条件を満たすかどうかを確認します。たとえば、短い文字列が長い文字列に現れるすべての位置を見つけます。

  2. 文字列または配列を指定し、この文字列の部分文字列または部分配列が特定の条件を満たすかどうかを確認します。例えば:

  • k個未満の異なる文字を含む最長の部分文字列

  • すべての文字が1回だけ表示される最長の部分文字列

加えて。他にもいくつか質問があります。しかし、定数はです。このような問題は、メイン文字列(メイン配列)とサブ文字列(サブ配列)の関係から切り離すことはできません。必要な時間計算量は多くの場合0(n)であり、空間計算量は一定であることがよくあります。


タイトルの説明:
n個の整数と正の整数sを含む配列が与えられた場合、配列内で合計が> = sである最小の連続サブ配列の長さを見つけます。

例:
指定された配列は2、3、1、2、4、3、sは7であるため、出力値は2、つまり4 +3である必要があります。


この問題を解決する方法は?

最初の方法は、各数値をループし、それを次の数値に加算してsより大きいかどうかを判断する暴力的な解決策です。最小値を求める場合、時間計算量はO(N ^ 2)であり、次のようになります。明らかに一般的な問題のためにタイムアウトします。したがって、ここでは、スライドウィンドウを使用して解決する必要があります。


スライディングウィンドウは、主に継続的な問題に対処するために使用されます。たとえば、連続部分文字列xxx、連続部分配列xxx "を解く問題。スライディングウィンドウについて考える必要があります。

タイプに関しては、主に次のものがあります。

  • 固定ウィンドウサイズ

  • ウィンドウサイズは固定されておらず、条件を満たす最大のウィンドウが解決されます

  • ウィンドウサイズは固定されていません。条件を満たす最小のウィンドウを解決してください。

ウィンドウサイズは固定されていません:

可変ウィンドウの場合、ウィンドウの左頂点と右頂点をそれぞれ表す左ポインターと右ポインターlとrも固定的に初期化します。保証する必要があります:

  1. lとrの両方が1に初期化されます

  2. rポインタが1ステップ移動します

  3. ウィンドウ内の連続要素がタイトルで定義された条件を満たすかどうかを判断します

  • 満足している場合は、最適解を更新する必要があるかどうかを判断し、必要に応じて最適解を更新します。Iポインタを動かして、ウィンドウサイズを小さくしてみてください。
  • ループ内で前のステップを実行します。それが満たされない場合は、rポインターを1つ増やし続けます。

時間計算量:0(n)


以下はコードです:

#include <iostream>
using namespace std;
#define inf 0x3f3f3f3f
int n,s,ans;
int a[1005];

int main()
{
    
    
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a[i];
	}
	cin>>s;//找出和>=s的最小连续子数组的长度 
	int l=1;//左指针 
	int r=1;//右指针 
	int tot=0;//记录子数组的和 
	ans=inf;
	for(r=1;r<=n;r++)
	{
    
    
		tot+=a[r];
		while(tot>=s)
		{
    
    
			ans=min(ans,r-l+1);//r-l+1为子数组长度
			tot-=a[l];
			l+=1;
		}
	}
	cout<<ans<<endl;
		
	return 0;
} 

おすすめ

転載: blog.csdn.net/weixin_45102820/article/details/114682560
おすすめ