怠惰ながん書き込みアルゴリズム(スライディングウィンドウ)

この記事では、主にleetcodeでのfuxuemingzhuのアイデアに言及するスライディングウィンドウアルゴリズムテンプレートを提供します


序文

「チャレンジプログラミングコンテスト」という本では、スライディングウィンドウは「ワームの方法」と呼ばれ、とても鮮やかだと思います。スライディングウィンドウの2つのポインタの移動プロセスは、バグのクロールプロセスと非常に似ているため、前足が移動していない場合は後足を移動し、後足が移動していない場合は前足を前方に移動します。

著者:fuxuemingzhu
リンク:https://leetcode-cn.com/problems/get-equal-substrings-within-budget/solution/fen-xiang-zhen-cang-de-hua-dong-chuang-k-e3rd/
ソース:LeetCode(LeetCode)の
著作権は作者に帰属します。商用の再版については、著者に連絡して許可を求め、非商用の再版については、出典を示してください。


ヒント:以下はこの記事の内容です。以下のケースは参照用です。

1つ、テンプレートコードとアイデア

テンプレート

public int findSubArray(nums) {
    
    
        
        int len=nums.length;//数组或字符串长度
        int left=0,right=0; //双指针,表示当前遍历的区间[left, right],闭区间
        
        int sums=0//用于统计子数组/子区间是否有效,根据题目可能会改成求和/计数
        int maxLength = 0 //保存最大的满足题目要求的子数组/子串长度

        while(right<len){
    
     //当右边的指针没有搜索到数组/字符串的结尾
            sums=sums+array[right];//增加当前右边指针的数字/字符的求和/计数
            while(区间[left, right]不符合题意){
    
    //此时需要一直移动左指针,直至找到一个符合题意的区间
                sums=sums-array[left];// 移动左指针前需要从counter中减少left位置字符的求和/计数
                left++;//真正的移动左指针,注意不能跟上面一行代码写反
            }
            //到内层的while结束时,我们找到了一个符合题意要求的子数组/子串
            maxLength=Math.max(maxLength,right-left+1);
            right++; //移动右指针,去探索新的区间
        }
        return maxLength;//找到符合题意的子数组/子字符串长度
    }
}

アイデア

  1. 現在移動している間隔を表すために、左と右の2つのポインターを定義します[left,right](ウィンドウとしても理解できます)。
  2. 合計と解像度を定義します。合計は各ウィンドウの結果を保存するために使用されます。これは主に条件が満たされているかどうかを判断するために使用され、解像度は条件に最適な結果を保存するために使用されます。
  3. 最初のwhileループは、右ポインターの位置が配列の境界を超えているかどうかを判別することです。右が新しい位置に到達するたびに、右ポインターの合計/カウントを増やす必要があります。
  4. 2番目のwhileループは、[left、right]間隔が質問の意味を満たす位置に左ポインターを右に移動することです。左が毎回新しい位置に移動すると、左ポインターの合計/カウント削減する必要があります。
  5. 2番目のwhileループの後、質問の意味を満たす[left、right]間隔を見つけることに成功し、質問の要件に従ってresの値を更新しました。この問題には最大間隔の長さが必要なので、resをmax(res、現在の間隔の長さ)に更新します。
  6. 満たされている間隔を見つけたら、右ポインタを1ビット右に移動して、条件を満たす次の間隔を見つけます。

2.特定の用途

トピック

leecodeは文字列を可能な限り等しくします

同じ長さの2つの文字列sとtを与えます。

sのi番目の文字をtのi番目の文字に変更するには、| s [i] -t [i] |のオーバーヘッドが必要です(オーバーヘッドは0の場合があります)。これは、ASCIIコード値の違いです。 2文字の絶対値。

文字列を変更するための最大予算はmaxCostです。文字列を変換する場合、総コストは予算以下である必要があります。これは、文字列の変換が不完全である可能性があることも意味します。

sの部分文字列をtの対応する部分文字列に変換できる場合は、変換できる最大長を返します。

sにtの対応する部分文字列に変換できる部分文字列がない場合、0が返されます。

例1:

入力:s = "abcd"、t = "bcdf"、コスト= 3
出力:3
説明:sの "abc"は "bcd"に変更できます。コストは3なので、最大長は3です。
例2:

入力:s = "abcd"、t = "cdef"、コスト= 3
出力:1
説明:sのいずれかの文字がtの対応する文字になりたい場合、コストは2です。したがって、最大長は1です。
例3:

入力:s = "abcd"、t = "acde"、cost = 0
出力:1
説明:変更を加えることができないため、最大長は1です。

促す:

1 <= s.length、t.length <= 10 ^ 5
0 <= maxCost <= 10 ^ 6s
とtの両方に小文字の英字のみが含まれます。
合格20,865提出45,442

出典:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/get-equal-substrings-within-budget
著作権はLeetCodeが所有しています商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。

コード

コードは次のとおりです(例):

class Solution {
    
    
    public static int equalSubstring(String s, String t, int maxCost) {
    
    

		int N = s.length();
        int[] sub = new int[N];
        
        for(int i=0;i<N;i++){
    
    
        	sub[i] = Math.abs(s.charAt(i)-t.charAt(i));
        }
        
        int r = 0,l = 0;
        int costs = 0;
        int res = 0;
        
        while(r<N){
    
    
        	costs+=sub[r];
        	
        	while(costs>maxCost){
    
    
        		costs-=sub[l];
        		l++;
        	}
        	
        	res = Math.max(r-l+1, res);
        	r++;
        }
        
        return res;
	}
}

総括する

怠惰な癌の解決策、参照のみ。このテンプレートを理解してからこの種の質問を書くとき、それは古代の詩を黙って書くことと何ら変わりはありません。

おすすめ

転載: blog.csdn.net/u013456390/article/details/113697856