繰り返し文字を含まない最長の部分文字列
このトピックは Leetcode からのもので、アドレスは次のとおりです: https://leetcode-cn.com/problems/longest-substring-without-repeat-characters/comments/
この解決策は、ネチズンの返信から得たもので、私自身の理解を少し追加したものです。アドレスは次のとおりです: Java Solution- 3. 繰り返し文字を含まない最長部分文字列- 繰り返し文字を含まない最長部分文字列- LeetCode (leetcode-cn.com) )
文字列 s が与えられた場合、繰り返し文字を含まない最長の部分文字列の長さを見つけてください。
例 1:
入力: s = "abcabcbb"
出力: 3
説明: 繰り返し文字を含まない最長の部分文字列は「abc」であるため、その長さは 3 です。
例 2:
入力: s = "bbbbb"
出力: 1
説明: 繰り返し文字を含まない最長の部分文字列は "b" であるため、その長さは 1 です。
例 3:
入力: s = "pwwkew"
出力: 3
説明: 繰り返し文字を含まない最長の部分文字列は「wke」であるため、その長さは 3 です。
答えは部分文字列の長さでなければならないことに注意してください。「pwke」は部分文字列ではなく部分列です。
例 4:
入力: s = ""
出力: 0
ヒント:
0 <= s.length <= 5 * 104
s は英語の文字、数字、記号、スペースで構成されます
問題解決のアイデア:
文字列を走査し、毎回 i 値を使用して記録し、i 値を遡らず、走査プロセス中に見つかった繰り返し文字の位置をフラグを使用して記録します。繰り返し文字が見つかった場合、i-flag は部分文字列の長さになります。このとき、フラグは部分文字列内の繰り返し文字の位置に再配置され、i は後方へのトラバースを続けます。ここで長さと結果レコードの長さです。
図:
コード:
/**
* length:计算当前无重复字符的子串长度
* result:存储最长子串长度
* i、flag:具体含义如图解所示
* s.charAt(i):i坐标下的字符
* s.indexOf(s.charAt(i),flag):flag位置后,i坐标下字符的第一次出现的坐标
*/
class Solution {
public int lengthOfLongestSubstring(String s) {
int i = 0;
int flag = 0;
int length = 0;
int result = 0;
while (i < s.length()) {
// pos:flag位置后,i坐标下字符的第一次出现的坐标
int pos = s.indexOf(s.charAt(i),flag);
// 没有重复字符情况下,pos=i,出现重复,进入if循环
if (pos < i) {
// 当前子串长度大于记录长度,则替换
if (length > result) {
result = length;
}
// 记录子串长度大于剩下字符长度,直接返回结果
if (result >= s.length() - pos - 1) {
return result;
}
// 子串长度为重复字符后一位到当前位置的长度
length = i - pos - 1;
// 子串头重新定位到重复字符的后一位
flag = pos + 1;
}
length++;
i++;
}
return length;
}
}