209. 最小長のサブアレイ
トピックの説明:
n
正の整数の配列と正の整数 を指定します target
。
配列内でその合計が長さ以上となる最小の 連続部分配列を検索し 、その長さを返します。一致する部分配列がない場合は、 を返します 。 target
[numsl, numsl+1, ..., numsr-1, numsr]
0
問題解決のアイデア:
質問から、この質問が正の数列であることがわかります。この質問では、最小の連続部分配列を見つける必要があります。部分配列の合計が sum であると仮定します。
左から右に、数値を加算するたびに合計が増加し、数値を減少させるたびに合計が減少すると仮定します。これが単調性です。
したがって、ウィンドウの左右の境界として 2 つのポインタを左右 (最初は両方とも 0 の位置にあります) として使用できます。右が右に移動すると、合計はウィンドウの合計になります。右が右に移動すると、合計はウィンドウの合計になります。 , 合計が増加します。左に移動すると合計が減少します (2 つのポインターが同じ方向に移動する場合、これを同じ方向のダブル ポインターと呼びます)。合計 >= ターゲットの場合はウィンドウを終了します (left++)。それ以外の場合はウィンドウに入ります。ウィンドウ (right++)、および長さ (最小長) を更新する必要があります。)。
時間計算量: コードは 2 レベルのループですが、 左 ポインタと 右 ポインタは戻りません。最大 n 回後方に移動します。したがって、時間計算量は O(N)です 。
解決策コード:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int length = INT_MAX;
int n = nums.size();
int left = 0;
int right = 0;
int sum = 0;
while(right<n)
{
sum+=nums[right];
while(sum>=target)
{
length=min(length,right-left+1);
sum-=nums[left++];
}
right++;
}
return length==INT_MAX?0:length;
}
};
3. 繰り返し文字を含まない最長の部分文字列
トピックの説明:
文字列を指定して 、繰り返し文字を含まない最長の部分文字 s
列の長さを 見つけてください 。
問題解決のアイデア:
まだ引き違い窓を使っている
解決策コード:
class Solution {
public:
bool str(string&s,int left,int right,char ch)
{
for(int i=left;i<=right;i++)
{
if(ch==s[i])
return false;
}
return true;
}
int lengthOfLongestSubstring(string s) {
int length=0;
int left=0,right=0;
int n=s.size();
while(right<n)
{
while(!str(s,left,right-1,s[right]))
left++;
length=max(length,right-left+1);
right++;
}
return length;
}
};