diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
index 0a34e8470465a..9d5d399aca7f6 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
@@ -26,7 +26,7 @@ tags:
输入: s = "abcabcbb"
-输出: 3
+输出: 3
解释: 因为无重复字符的最长子串是 "abc"
,所以其长度为 3。
@@ -62,26 +62,15 @@ tags:
-### 方法一:双指针 + 哈希表
-
-定义一个哈希表记录当前窗口内出现的字符,记 $i$ 和 $j$ 分别表示不重复子串的开始位置和结束位置,无重复字符子串的最大长度记为 `ans`。
+### 方法一:滑动窗口
-遍历字符串 `s` 的每个字符 $s[j]$,我们记为 $c$。若 $s[i..j-1]$ 窗口内存在 $c$,则 $i$ 循环向右移动,更新哈希表,直至 $s[i..j-1]$ 窗口不存在 `c`,循环结束。将 `c` 加入哈希表中,此时 $s[i..j]$ 窗口内不含重复元素,更新 `ans` 的最大值。
+我们可以用两个指针 $l$ 和 $r$ 维护一个滑动窗口,使其始终满足窗口内没有重复字符,初始时 $l$ 和 $r$ 都指向字符串的第一个字符。用一个哈希表或者长度为 $128$ 的数组 $\textit{cnt}$ 来记录每个字符出现的次数,其中 $\textit{cnt}[c]$ 表示字符 $c$ 出现的次数。
-最后返回 `ans` 即可。
+接下来,我们依次移动右指针 $r$,每次移动时,将 $\textit{cnt}[s[r]]$ 的值加 $1$,然后判断当前窗口 $[l, r]$ 内 $\textit{cnt}[s[r]]$ 是否大于 $1$,如果大于 $1$,说明当前窗口内有重复字符,我们需要移动左指针 $l$,直到窗口内没有重复字符为止。然后,我们更新答案 $\textit{ans} = \max(\textit{ans}, r - l + 1)$。
-时间复杂度 $O(n)$,其中 $n$ 表示字符串 `s` 的长度。
+最终,我们返回答案 $\textit{ans}$ 即可。
-双指针算法模板:
-
-```java
-for (int i = 0, j = 0; i < n; ++i) {
- while (j < i && check(j, i)) {
- ++j;
- }
- // 具体问题的逻辑
-}
-```
+时间复杂度 $O(n)$,其中 $n$ 为字符串的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 表示字符集,这里 $\Sigma$ 的大小为 $128$。
@@ -90,14 +79,14 @@ for (int i = 0, j = 0; i < n; ++i) {
```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
- ss = set()
- ans = i = 0
- for j, c in enumerate(s):
- while c in ss:
- ss.remove(s[i])
- i += 1
- ss.add(c)
- ans = max(ans, j - i + 1)
+ cnt = Counter()
+ ans = l = 0
+ for r, c in enumerate(s):
+ cnt[c] += 1
+ while cnt[c] > 1:
+ cnt[s[l]] -= 1
+ l += 1
+ ans = max(ans, r - l + 1)
return ans
```
@@ -106,15 +95,15 @@ class Solution:
```java
class Solution {
public int lengthOfLongestSubstring(String s) {
- boolean[] ss = new boolean[128];
- int ans = 0;
- for (int i = 0, j = 0; j < s.length(); ++j) {
- char c = s.charAt(j);
- while (ss[c]) {
- ss[s.charAt(i++)] = false;
+ int[] cnt = new int[128];
+ int ans = 0, n = s.length();
+ for (int l = 0, r = 0; r < n; ++r) {
+ char c = s.charAt(r);
+ ++cnt[c];
+ while (cnt[c] > 1) {
+ --cnt[s.charAt(l++)];
}
- ss[c] = true;
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -127,14 +116,14 @@ class Solution {
class Solution {
public:
int lengthOfLongestSubstring(string s) {
- bool ss[128]{};
- int ans = 0;
- for (int i = 0, j = 0; j < s.size(); ++j) {
- while (ss[s[j]]) {
- ss[s[i++]] = false;
+ int cnt[128]{};
+ int ans = 0, n = s.size();
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss[s[j]] = true;
- ans = max(ans, j - i + 1);
+ ans = max(ans, r - l + 1);
}
return ans;
}
@@ -145,14 +134,15 @@ public:
```go
func lengthOfLongestSubstring(s string) (ans int) {
- ss := [128]bool{}
- for i, j := 0, 0; j < len(s); j++ {
- for ss[s[j]] {
- ss[s[i]] = false
- i++
+ cnt := [128]int{}
+ l := 0
+ for r, c := range s {
+ cnt[c]++
+ for cnt[c] > 1 {
+ cnt[s[l]]--
+ l++
}
- ss[s[j]] = true
- ans = max(ans, j-i+1)
+ ans = max(ans, r-l+1)
}
return
}
@@ -163,13 +153,15 @@ func lengthOfLongestSubstring(s string) (ans int) {
```ts
function lengthOfLongestSubstring(s: string): number {
let ans = 0;
- const ss: Set = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const cnt = new Map();
+ const n = s.length;
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r])! > 1) {
+ cnt.set(s[l], cnt.get(s[l])! - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -178,24 +170,22 @@ function lengthOfLongestSubstring(s: string): number {
#### Rust
```rust
-use std::collections::HashSet;
-
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
- let s = s.as_bytes();
- let mut ss = HashSet::new();
- let mut i = 0;
- s.iter()
- .map(|c| {
- while ss.contains(&c) {
- ss.remove(&s[i]);
- i += 1;
- }
- ss.insert(c);
- ss.len()
- })
- .max()
- .unwrap_or(0) as i32
+ let mut cnt = [0; 128];
+ let mut ans = 0;
+ let mut l = 0;
+ let chars: Vec = s.chars().collect();
+ let n = chars.len();
+ for (r, &c) in chars.iter().enumerate() {
+ cnt[c as usize] += 1;
+ while cnt[c as usize] > 1 {
+ cnt[chars[l] as usize] -= 1;
+ l += 1;
+ }
+ ans = ans.max((r - l + 1) as i32);
+ }
+ ans
}
}
```
@@ -209,13 +199,15 @@ impl Solution {
*/
var lengthOfLongestSubstring = function (s) {
let ans = 0;
- const ss = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const n = s.length;
+ const cnt = new Map();
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r]) > 1) {
+ cnt.set(s[l], cnt.get(s[l]) - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
};
@@ -226,14 +218,15 @@ var lengthOfLongestSubstring = function (s) {
```cs
public class Solution {
public int LengthOfLongestSubstring(string s) {
+ int n = s.Length;
int ans = 0;
- var ss = new HashSet();
- for (int i = 0, j = 0; j < s.Length; ++j) {
- while (ss.Contains(s[j])) {
- ss.Remove(s[i++]);
+ var cnt = new int[128];
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss.Add(s[j]);
- ans = Math.Max(ans, j - i + 1);
+ ans = Math.Max(ans, r - l + 1);
}
return ans;
}
@@ -244,19 +237,18 @@ public class Solution {
```php
class Solution {
- /**
- * @param String $s
- * @return Integer
- */
function lengthOfLongestSubstring($s) {
+ $n = strlen($s);
$ans = 0;
- $ss = [];
- for ($i = 0, $j = 0; $j < strlen($s); ++$j) {
- while (in_array($s[$j], $ss)) {
- unset($ss[array_search($s[$i++], $ss)]);
+ $cnt = array_fill(0, 128, 0);
+ $l = 0;
+ for ($r = 0; $r < $n; ++$r) {
+ $cnt[ord($s[$r])]++;
+ while ($cnt[ord($s[$r])] > 1) {
+ $cnt[ord($s[$l])]--;
+ $l++;
}
- $ss[] = $s[$j];
- $ans = max($ans, $j - $i + 1);
+ $ans = max($ans, $r - $l + 1);
}
return $ans;
}
@@ -268,62 +260,40 @@ class Solution {
```swift
class Solution {
func lengthOfLongestSubstring(_ s: String) -> Int {
- var map = [Character: Int]()
- var currentStartingIndex = 0
- var i = 0
- var maxLength = 0
- for char in s {
- if map[char] != nil {
- if map[char]! >= currentStartingIndex {
- maxLength = max(maxLength, i - currentStartingIndex)
- currentStartingIndex = map[char]! + 1
- }
+ let n = s.count
+ var ans = 0
+ var cnt = [Int](repeating: 0, count: 128)
+ var l = 0
+ let sArray = Array(s)
+ for r in 0.. 1 {
+ cnt[Int(sArray[l].asciiValue!)] -= 1
+ l += 1
}
- map[char] = i
- i += 1
+ ans = max(ans, r - l + 1)
}
- return max(maxLength, i - currentStartingIndex)
+ return ans
}
}
```
-#### Nim
-
-```nim
-proc lengthOfLongestSubstring(s: string): int =
- var
- i = 0
- j = 0
- res = 0
- literals: set[char] = {}
-
- while i < s.len:
- while s[i] in literals:
- if s[j] in literals:
- excl(literals, s[j])
- j += 1
- literals.incl(s[i]) # Uniform Function Call Syntax f(x) = x.f
- res = max(res, i - j + 1)
- i += 1
-
- result = res # result has the default return value
-```
-
#### Kotlin
```kotlin
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
- var char_set = BooleanArray(128)
- var left = 0
+ val n = s.length
var ans = 0
- s.forEachIndexed { right, c ->
- while (char_set[c.code]) {
- char_set[s[left].code] = false
- left++
+ val cnt = IntArray(128)
+ var l = 0
+ for (r in 0 until n) {
+ cnt[s[r].toInt()]++
+ while (cnt[s[r].toInt()] > 1) {
+ cnt[s[l].toInt()]--
+ l++
}
- char_set[c.code] = true
- ans = Math.max(ans, right - left + 1)
+ ans = Math.max(ans, r - l + 1)
}
return ans
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
index 7218d6526623c..c8302cd9b1aab 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
@@ -60,26 +60,15 @@ Notice that the answer must be a substring, "pwke" is a subsequence an
-### Solution 1: Two pointers + Hash Table
+### Solution 1: Sliding Window
-Define a hash table to record the characters in the current window. Let $i$ and $j$ represent the start and end positions of the non-repeating substring, respectively. The length of the longest non-repeating substring is recorded by `ans`.
+We can use two pointers $l$ and $r$ to maintain a sliding window that always satisfies the condition of having no repeating characters within the window. Initially, both $l$ and $r$ point to the first character of the string. We use a hash table or an array of length $128$ called $\textit{cnt}$ to record the number of occurrences of each character, where $\textit{cnt}[c]$ represents the number of occurrences of character $c$.
-For each character $s[j]$ in the string `s`, we call it $c$. If $c$ exists in the window $s[i..j-1]$, we move $i$ to the right until $s[i..j-1]$ does not contain `c`. Then we add `c` to the hash table. At this time, the window $s[i..j]$ does not contain repeated elements, and we update the maximum value of `ans`.
+Next, we move the right pointer $r$ one step at a time. Each time we move it, we increment the value of $\textit{cnt}[s[r]]$ by $1$, and then check if the value of $\textit{cnt}[s[r]]$ is greater than $1$ within the current window $[l, r]$. If it is greater than $1$, it means there are repeating characters within the current window, and we need to move the left pointer $l$ until there are no repeating characters within the window. Then, we update the answer $\textit{ans} = \max(\textit{ans}, r - l + 1)$.
-Finally, return `ans`.
+Finally, we return the answer $\textit{ans}$.
-The time complexity is $O(n)$, where $n$ represents the length of the string `s`.
-
-Two pointers algorithm template:
-
-```java
-for (int i = 0, j = 0; i < n; ++i) {
- while (j < i && check(j, i)) {
- ++j;
- }
- // logic of specific problem
-}
-```
+The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(|\Sigma|)$, where $\Sigma$ represents the character set, and the size of $\Sigma$ is $128$.
@@ -88,14 +77,14 @@ for (int i = 0, j = 0; i < n; ++i) {
```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
- ss = set()
- ans = i = 0
- for j, c in enumerate(s):
- while c in ss:
- ss.remove(s[i])
- i += 1
- ss.add(c)
- ans = max(ans, j - i + 1)
+ cnt = Counter()
+ ans = l = 0
+ for r, c in enumerate(s):
+ cnt[c] += 1
+ while cnt[c] > 1:
+ cnt[s[l]] -= 1
+ l += 1
+ ans = max(ans, r - l + 1)
return ans
```
@@ -104,15 +93,15 @@ class Solution:
```java
class Solution {
public int lengthOfLongestSubstring(String s) {
- boolean[] ss = new boolean[128];
- int ans = 0;
- for (int i = 0, j = 0; j < s.length(); ++j) {
- char c = s.charAt(j);
- while (ss[c]) {
- ss[s.charAt(i++)] = false;
+ int[] cnt = new int[128];
+ int ans = 0, n = s.length();
+ for (int l = 0, r = 0; r < n; ++r) {
+ char c = s.charAt(r);
+ ++cnt[c];
+ while (cnt[c] > 1) {
+ --cnt[s.charAt(l++)];
}
- ss[c] = true;
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -125,14 +114,14 @@ class Solution {
class Solution {
public:
int lengthOfLongestSubstring(string s) {
- bool ss[128]{};
- int ans = 0;
- for (int i = 0, j = 0; j < s.size(); ++j) {
- while (ss[s[j]]) {
- ss[s[i++]] = false;
+ int cnt[128]{};
+ int ans = 0, n = s.size();
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss[s[j]] = true;
- ans = max(ans, j - i + 1);
+ ans = max(ans, r - l + 1);
}
return ans;
}
@@ -143,14 +132,15 @@ public:
```go
func lengthOfLongestSubstring(s string) (ans int) {
- ss := [128]bool{}
- for i, j := 0, 0; j < len(s); j++ {
- for ss[s[j]] {
- ss[s[i]] = false
- i++
+ cnt := [128]int{}
+ l := 0
+ for r, c := range s {
+ cnt[c]++
+ for cnt[c] > 1 {
+ cnt[s[l]]--
+ l++
}
- ss[s[j]] = true
- ans = max(ans, j-i+1)
+ ans = max(ans, r-l+1)
}
return
}
@@ -161,13 +151,15 @@ func lengthOfLongestSubstring(s string) (ans int) {
```ts
function lengthOfLongestSubstring(s: string): number {
let ans = 0;
- const ss: Set = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const cnt = new Map();
+ const n = s.length;
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r])! > 1) {
+ cnt.set(s[l], cnt.get(s[l])! - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -176,24 +168,22 @@ function lengthOfLongestSubstring(s: string): number {
#### Rust
```rust
-use std::collections::HashSet;
-
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
- let s = s.as_bytes();
- let mut ss = HashSet::new();
- let mut i = 0;
- s.iter()
- .map(|c| {
- while ss.contains(&c) {
- ss.remove(&s[i]);
- i += 1;
- }
- ss.insert(c);
- ss.len()
- })
- .max()
- .unwrap_or(0) as i32
+ let mut cnt = [0; 128];
+ let mut ans = 0;
+ let mut l = 0;
+ let chars: Vec = s.chars().collect();
+ let n = chars.len();
+ for (r, &c) in chars.iter().enumerate() {
+ cnt[c as usize] += 1;
+ while cnt[c as usize] > 1 {
+ cnt[chars[l] as usize] -= 1;
+ l += 1;
+ }
+ ans = ans.max((r - l + 1) as i32);
+ }
+ ans
}
}
```
@@ -207,13 +197,15 @@ impl Solution {
*/
var lengthOfLongestSubstring = function (s) {
let ans = 0;
- const ss = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const n = s.length;
+ const cnt = new Map();
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r]) > 1) {
+ cnt.set(s[l], cnt.get(s[l]) - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
};
@@ -224,14 +216,15 @@ var lengthOfLongestSubstring = function (s) {
```cs
public class Solution {
public int LengthOfLongestSubstring(string s) {
+ int n = s.Length;
int ans = 0;
- var ss = new HashSet();
- for (int i = 0, j = 0; j < s.Length; ++j) {
- while (ss.Contains(s[j])) {
- ss.Remove(s[i++]);
+ var cnt = new int[128];
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss.Add(s[j]);
- ans = Math.Max(ans, j - i + 1);
+ ans = Math.Max(ans, r - l + 1);
}
return ans;
}
@@ -242,19 +235,18 @@ public class Solution {
```php
class Solution {
- /**
- * @param String $s
- * @return Integer
- */
function lengthOfLongestSubstring($s) {
+ $n = strlen($s);
$ans = 0;
- $ss = [];
- for ($i = 0, $j = 0; $j < strlen($s); ++$j) {
- while (in_array($s[$j], $ss)) {
- unset($ss[array_search($s[$i++], $ss)]);
+ $cnt = array_fill(0, 128, 0);
+ $l = 0;
+ for ($r = 0; $r < $n; ++$r) {
+ $cnt[ord($s[$r])]++;
+ while ($cnt[ord($s[$r])] > 1) {
+ $cnt[ord($s[$l])]--;
+ $l++;
}
- $ss[] = $s[$j];
- $ans = max($ans, $j - $i + 1);
+ $ans = max($ans, $r - $l + 1);
}
return $ans;
}
@@ -266,62 +258,40 @@ class Solution {
```swift
class Solution {
func lengthOfLongestSubstring(_ s: String) -> Int {
- var map = [Character: Int]()
- var currentStartingIndex = 0
- var i = 0
- var maxLength = 0
- for char in s {
- if map[char] != nil {
- if map[char]! >= currentStartingIndex {
- maxLength = max(maxLength, i - currentStartingIndex)
- currentStartingIndex = map[char]! + 1
- }
+ let n = s.count
+ var ans = 0
+ var cnt = [Int](repeating: 0, count: 128)
+ var l = 0
+ let sArray = Array(s)
+ for r in 0.. 1 {
+ cnt[Int(sArray[l].asciiValue!)] -= 1
+ l += 1
}
- map[char] = i
- i += 1
+ ans = max(ans, r - l + 1)
}
- return max(maxLength, i - currentStartingIndex)
+ return ans
}
}
```
-#### Nim
-
-```nim
-proc lengthOfLongestSubstring(s: string): int =
- var
- i = 0
- j = 0
- res = 0
- literals: set[char] = {}
-
- while i < s.len:
- while s[i] in literals:
- if s[j] in literals:
- excl(literals, s[j])
- j += 1
- literals.incl(s[i]) # Uniform Function Call Syntax f(x) = x.f
- res = max(res, i - j + 1)
- i += 1
-
- result = res # result has the default return value
-```
-
#### Kotlin
```kotlin
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
- var char_set = BooleanArray(128)
- var left = 0
+ val n = s.length
var ans = 0
- s.forEachIndexed { right, c ->
- while (char_set[c.code]) {
- char_set[s[left].code] = false
- left++
+ val cnt = IntArray(128)
+ var l = 0
+ for (r in 0 until n) {
+ cnt[s[r].toInt()]++
+ while (cnt[s[r].toInt()] > 1) {
+ cnt[s[l].toInt()]--
+ l++
}
- char_set[c.code] = true
- ans = Math.max(ans, right - left + 1)
+ ans = Math.max(ans, r - l + 1)
}
return ans
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp
index 980f98df2cc44..549f59f0ae8b7 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp
@@ -1,15 +1,15 @@
class Solution {
public:
int lengthOfLongestSubstring(string s) {
- bool ss[128]{};
- int ans = 0;
- for (int i = 0, j = 0; j < s.size(); ++j) {
- while (ss[s[j]]) {
- ss[s[i++]] = false;
+ int cnt[128]{};
+ int ans = 0, n = s.size();
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss[s[j]] = true;
- ans = max(ans, j - i + 1);
+ ans = max(ans, r - l + 1);
}
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs
index 2c29e34899025..044baded41e3a 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs
@@ -1,13 +1,14 @@
public class Solution {
public int LengthOfLongestSubstring(string s) {
+ int n = s.Length;
int ans = 0;
- var ss = new HashSet();
- for (int i = 0, j = 0; j < s.Length; ++j) {
- while (ss.Contains(s[j])) {
- ss.Remove(s[i++]);
+ var cnt = new int[128];
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss.Add(s[j]);
- ans = Math.Max(ans, j - i + 1);
+ ans = Math.Max(ans, r - l + 1);
}
return ans;
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go
index 68104afd448ff..365301a1ce97f 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go
@@ -1,12 +1,13 @@
func lengthOfLongestSubstring(s string) (ans int) {
- ss := [128]bool{}
- for i, j := 0, 0; j < len(s); j++ {
- for ss[s[j]] {
- ss[s[i]] = false
- i++
+ cnt := [128]int{}
+ l := 0
+ for r, c := range s {
+ cnt[c]++
+ for cnt[c] > 1 {
+ cnt[s[l]]--
+ l++
}
- ss[s[j]] = true
- ans = max(ans, j-i+1)
+ ans = max(ans, r-l+1)
}
return
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java
index 28dda65b2442d..574f3c62a27e8 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java
@@ -1,15 +1,15 @@
class Solution {
public int lengthOfLongestSubstring(String s) {
- boolean[] ss = new boolean[128];
- int ans = 0;
- for (int i = 0, j = 0; j < s.length(); ++j) {
- char c = s.charAt(j);
- while (ss[c]) {
- ss[s.charAt(i++)] = false;
+ int[] cnt = new int[128];
+ int ans = 0, n = s.length();
+ for (int l = 0, r = 0; r < n; ++r) {
+ char c = s.charAt(r);
+ ++cnt[c];
+ while (cnt[c] > 1) {
+ --cnt[s.charAt(l++)];
}
- ss[c] = true;
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js
index d87d290b2cfb3..16f64428d105f 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js
@@ -4,13 +4,15 @@
*/
var lengthOfLongestSubstring = function (s) {
let ans = 0;
- const ss = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const n = s.length;
+ const cnt = new Map();
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r]) > 1) {
+ cnt.set(s[l], cnt.get(s[l]) - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
};
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt
index f98e101a2f826..82cba82a59d3e 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt
@@ -1,15 +1,16 @@
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
- var char_set = BooleanArray(128)
- var left = 0
+ val n = s.length
var ans = 0
- s.forEachIndexed { right, c ->
- while (char_set[c.code]) {
- char_set[s[left].code] = false
- left++
+ val cnt = IntArray(128)
+ var l = 0
+ for (r in 0 until n) {
+ cnt[s[r].toInt()]++
+ while (cnt[s[r].toInt()] > 1) {
+ cnt[s[l].toInt()]--
+ l++
}
- char_set[c.code] = true
- ans = Math.max(ans, right - left + 1)
+ ans = Math.max(ans, r - l + 1)
}
return ans
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.nim b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.nim
deleted file mode 100644
index 1275a35bfbee6..0000000000000
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.nim
+++ /dev/null
@@ -1,17 +0,0 @@
-proc lengthOfLongestSubstring(s: string): int =
- var
- i = 0
- j = 0
- res = 0
- literals: set[char] = {}
-
- while i < s.len:
- while s[i] in literals:
- if s[j] in literals:
- excl(literals, s[j])
- j += 1
- literals.incl(s[i]) # Uniform Function Call Syntax f(x) = x.f
- res = max(res, i - j + 1)
- i += 1
-
- result = res # result has the default return value
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php
index d51d37abe0e51..af9ebc954a1d7 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php
@@ -1,18 +1,17 @@
class Solution {
- /**
- * @param String $s
- * @return Integer
- */
function lengthOfLongestSubstring($s) {
+ $n = strlen($s);
$ans = 0;
- $ss = [];
- for ($i = 0, $j = 0; $j < strlen($s); ++$j) {
- while (in_array($s[$j], $ss)) {
- unset($ss[array_search($s[$i++], $ss)]);
+ $cnt = array_fill(0, 128, 0);
+ $l = 0;
+ for ($r = 0; $r < $n; ++$r) {
+ $cnt[ord($s[$r])]++;
+ while ($cnt[ord($s[$r])] > 1) {
+ $cnt[ord($s[$l])]--;
+ $l++;
}
- $ss[] = $s[$j];
- $ans = max($ans, $j - $i + 1);
+ $ans = max($ans, $r - $l + 1);
}
return $ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py
index 752e44282faee..828f12c0e90c7 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py
@@ -1,11 +1,11 @@
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
- ss = set()
- ans = i = 0
- for j, c in enumerate(s):
- while c in ss:
- ss.remove(s[i])
- i += 1
- ss.add(c)
- ans = max(ans, j - i + 1)
+ cnt = Counter()
+ ans = l = 0
+ for r, c in enumerate(s):
+ cnt[c] += 1
+ while cnt[c] > 1:
+ cnt[s[l]] -= 1
+ l += 1
+ ans = max(ans, r - l + 1)
return ans
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs
index 64e43f86096f5..ca4557f31fda6 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs
@@ -1,20 +1,18 @@
-use std::collections::HashSet;
-
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
- let s = s.as_bytes();
- let mut ss = HashSet::new();
- let mut i = 0;
- s.iter()
- .map(|c| {
- while ss.contains(&c) {
- ss.remove(&s[i]);
- i += 1;
- }
- ss.insert(c);
- ss.len()
- })
- .max()
- .unwrap_or(0) as i32
+ let mut cnt = [0; 128];
+ let mut ans = 0;
+ let mut l = 0;
+ let chars: Vec = s.chars().collect();
+ let n = chars.len();
+ for (r, &c) in chars.iter().enumerate() {
+ cnt[c as usize] += 1;
+ while cnt[c as usize] > 1 {
+ cnt[chars[l] as usize] -= 1;
+ l += 1;
+ }
+ ans = ans.max((r - l + 1) as i32);
+ }
+ ans
}
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift
index 02462178bdfd5..672a8f0f20787 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift
@@ -1,19 +1,18 @@
class Solution {
func lengthOfLongestSubstring(_ s: String) -> Int {
- var map = [Character: Int]()
- var currentStartingIndex = 0
- var i = 0
- var maxLength = 0
- for char in s {
- if map[char] != nil {
- if map[char]! >= currentStartingIndex {
- maxLength = max(maxLength, i - currentStartingIndex)
- currentStartingIndex = map[char]! + 1
- }
+ let n = s.count
+ var ans = 0
+ var cnt = [Int](repeating: 0, count: 128)
+ var l = 0
+ let sArray = Array(s)
+ for r in 0.. 1 {
+ cnt[Int(sArray[l].asciiValue!)] -= 1
+ l += 1
}
- map[char] = i
- i += 1
+ ans = max(ans, r - l + 1)
}
- return max(maxLength, i - currentStartingIndex)
+ return ans
}
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts
index 6f4d8610c0bb0..f37a5ffaa95b6 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts
@@ -1,12 +1,14 @@
function lengthOfLongestSubstring(s: string): number {
let ans = 0;
- const ss: Set = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const cnt = new Map();
+ const n = s.length;
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r])! > 1) {
+ cnt.set(s[l], cnt.get(s[l])! - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}