LeetCode 問題作成日記 003 - 繰り返しのない最長の部分文字列

LeetCode3——繰り返しのない最長の部分文字列

完成時期:2022/09/15

質問幹

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

自分の考え

   この質問では繰り返しのない最長の部分文字列が必要であるため、文字列をトラバースするために 2 つのポインターを使用することを考えるのは自然であり、その後、繰り返しのないキーワードについて数学で集合を考えるのが自然です。したがって、考え方は非常に明確で、走査した文字をセットに追加し、次の文字を表示するときにそのセットがセットに含まれているかどうかを確認するだけで済みます。それがセットに含まれている場合は、レコード変数を最大長 で更新しますmaxLength。値は です。これはj-i、この時点で重複が発生し、 j の位置がすでに重複文字列上にあるためです。私たちにとっては開始文字列なので、実際にはj-i+1-1に簡略化されますj-i

   テストの過程で、最初から最後まで繰り返しがないという特殊な状況に遭遇しました。"qwert0 *894/"繰り返しがないため、セットに含まれるかどうかの条件に基づいて更新することはできませんがmaxLength、この場合、2 番目のポインタは文字列の末尾を指している必要があると考えられます。そこで最終判定を加えます. 2番目のポインタが最後まで到達したら再度更新しますmaxLengthが、この時点ではj-i+1まだ繰り返して文字列の最後まで到達していないので、先頭の文字を補足する必要があります。 。

   時間計算量は O(n^2) です。

#include <string>
#include <set>
using namespace std;

class Solution {
    
    
public:
    int lengthOfLongestSubstring(string s) {
    
    
        if (s.length() <= 1) {
    
    
            return s.length();
        }

        set<char> charHash;
        int maxLength = 0;

        for (int i = 0; i < s.length()-1; i++) {
    
    
            charHash.insert(s[i]);
            for (int j = i + 1; j < s.length(); j++) {
      
      
                int exist = charHash.count(s[j]);
                charHash.insert(s[j]);
                if (exist) {
      
      
                    maxLength = maxLength > (j - i) ? maxLength : (j - i);  // 更新最大子串长度
                    break;
                }
                if (j == s.length() - 1) {
    
    
                    maxLength = maxLength > (j - i + 1) ? maxLength : (j - i + 1);  // 更新最大子串长度
                }
            }
            charHash.clear();
        }

        return maxLength;
    }
};

問題解決のアイデア

   スライディング ウィンドウ、ウィンドウ左ポインタ、ウィンドウ右ポインタを使用し、セットを使用してウィンドウ内の文字を保存します。重複が発生した場合、ウィンドウの左ポインタは 1 ビット右に移動し、転置された文字はウィンドウ内で消去されます。セット。私自身の考えと似ています。

class Solution {
    
    
public:
    int lengthOfLongestSubstring(string s) {
    
    
        set<char> charSet;
        int n = s.length();
        int rk = -1;    // 滑动窗的右指针
        int maxLength = 0;

        for (int i = 0; i < n; i++) {
    
    
            if (i != 0) {
    
    
                charSet.erase(s[i-1]);
            }

            while (rk < n-1 && !charSet.count(s[rk + 1])) {
    
    			// 右指针寻找有无重复字符
                charSet.insert(s[rk + 1]);
                rk++;
            }

            maxLength = max(maxLength, (rk - i + 1));
        }

        return maxLength;
    }
};

テストコード

#include "Solution.cpp"
#include <iostream>
using namespace std;

int main(void) {
    
    
	string s = "";
	Solution solution;

	int maxLength  = solution.lengthOfLongestSubstring(s);
	//cout << s.length();
	cout << maxLength;

	return 0;
}

おすすめ

転載: blog.csdn.net/qq_43419761/article/details/130263119