繰り返しのない文字の最長部分文字列
難易度:穏健派
説明:
文字列を考えると、あなたは、繰り返し文字の最長の文字列のサブ長さを含んでいないかを調べます。
例:
- 入力: "abcabcbb"
出力:3
説明:繰り返しのない文字の最長のサブストリングが「ABC」であるので、その長さは3ですので。
- 入力: "BBBBB"
出力:1
説明:その長さが1になるように、最長のサブ文字列は、「B」せずに文字を繰り返しているため。
- 入力: "pwwkew"
出力:3
説明:最長のサブ文字列は「WKE」せずに文字を繰り返しているので、その長さは3ですので。
- 入力: "dvdf"
出力:3
説明:最長のサブ文字列は「VDF」せずに文字を繰り返しているので、その長さは3ですので。
- 入力: "asjrgapa"
出力:6
説明:最長部分文字列は「sjrgap」せずに文字を繰り返しているので、その長さは6ですので。
- 入力: "!Aabaab BB"
出力:3
説明:「!AB」最長のサブ文字列はなしで文字を繰り返して、だから、その長さは3ですので。
- 入力: "ABCB"
出力:3
説明:繰り返しのない文字の最長のサブストリングが「ABC」であるので、その長さは3ですので。
- 入力: "asljlj"
出力:4
説明:その長さが4になるように、最長のサブ文字列は、「aslj」せずに文字を繰り返しているため。
- 入力: "qwnfenpglqdq"
出力:8
説明:最長のサブ文字列は「fenpglqd」せずに文字を繰り返しているので、その長さが8であるため。
アイデアの分析:
キーは、文字の繰り返しイベント内の文字をどのようにインデックスを更新するために繰り返されていないということです
コードテンプレート:
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function (s) {
}
考えます
A
考えます
再び
見て
答え
ケース
コード:
- 文字、文字インデックスの更新を持つオブジェクトの保存場所は時に重複した文字が繰り返されることはありません。
var lengthOfLongestSubstring = function (s) {
let obj = {}; // 用于储存字符出现的位置
let res = 0; // 最大值
let j = 0; // 不重复字符的index
for (let i = 0; i < s.length; i++) {
// 当前值是否在对象中存储过
const value = obj[s[i]]
if (value !== undefined) {
// 更新上一次重复值的index
// value + 1 跳过之前重复的字符
// j: 之前不重复的index 重复字符 需要全部跳过
j = Math.max(value + 1, j)
}
// 每个字符都计算一下最长不重复值 保存最大值
// 不重复最长长度 = 当前index - 上一次重复值的index + index从0开始 长度从1开始
res = Math.max(res, i - j + 1);
// 存/更新 字符串index
obj[s[i]] = i
}
return res;
};
- 左から右、文字ごとに繰り返されるかどうかを確認するために検索。
var lengthOfLongestSubstring = function (s) {
var i = 0, // 不重复字符的index
res = 0; // 更新无重复字符的长度
for (j = 0; j < s.length; j++) {
// 查找:不重复字符-当前index之间 有没有出现当前字符
let index = s.slice(i, j).indexOf(s[j])
if (index === -1) {
// 更新无重复字符的长度:当前index-不重复字符的index + 长度从1开始算
res = Math.max(res, j - i + 1);
} else {
// 更新i = 不重复字符的index
// 不重复字符的index = 原不重复的字符index + i-j中出现重复字符的index + 跳过该重复字符
i = i + index + 1;
}
}
return res;
};