mirror of
https://github.com/prdlk/leetcode.git
synced 2026-11-02 13:12:44 +00:00
docs(docs): add longest‑substring problem page and sliding‑window reference with SVG illustrations
This commit is contained in:
1 parent
fd0d6c6ea5
commit
bc2269d9dd
5 files changed
+336
No files matched your search
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: '3. Longest Substring Without Repeating Characters'
|
||||
description: Given a string s, find the length of the longest substring without duplicate characters
|
||||
sidebar:
|
||||
label: 'Longest Substring Without Repeating Characters'
|
||||
badge: 'Medium'
|
||||
---
|
||||
|
||||
<Badge variant="accent">Sliding Window</Badge>
|
||||
|
||||
### Example 1:
|
||||
- Input: `s = "abcabcbb"`
|
||||
- Output: `3`
|
||||
- Explanation: The answer is "abc", with the length of `3`. Note that "bca" and "cab" are also correct answers.
|
||||
|
||||
### Example 2:
|
||||
- Input: `s = "bbbbb"`
|
||||
- Output: `1`
|
||||
- Explanation: The answer is "b", with the length of `1`.
|
||||
|
||||
### Example 3:
|
||||
- Input: `s = "pwwkew"`
|
||||
- Output: `3`
|
||||
- Explanation: The answer is "wke", with the length of `3`. Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
|
||||
|
||||
### Constraints:
|
||||
|
||||
- `0 <= s.length <= 10^5`
|
||||
- `s` consists of English letters, digits, symbols and spaces.
|
||||
|
||||
## Solution
|
||||
|
||||
```py
|
||||
class Solution:
|
||||
def lengthOfLongestSubstring(self, s: str) -> int:
|
||||
left = 0
|
||||
ans = 0
|
||||
seen = set()
|
||||
for right, c in enumerate(s):
|
||||
while c in seen:
|
||||
seen.remove(s[left])
|
||||
left += 1
|
||||
seen.add(c)
|
||||
ans = max(ans, right - left + 1)
|
||||
|
||||
return ans
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Sliding Window
|
||||
description: 'Sliding window is a specialized two-pointer family where the pointers define a contiguous interval and you maintain information about that entire interval as it moves.'
|
||||
---
|
||||
|
||||
:::warning
|
||||
This is the family where invariants matter the most
|
||||
:::
|
||||
|
||||
## What Makes Sliding Window Different?
|
||||
|
||||
Many problems have two moving boundaries. That alone does not make them sliding window problems.
|
||||
|
||||
A problem belongs to this family when:
|
||||
|
||||
- the answer depends on the subarray or substring between left and right
|
||||
- you can update the window state incrementally as elements enter or leave
|
||||
- you maintain a condition that tells you whether the window is valid
|
||||
|
||||
## What is an Invariant?
|
||||
|
||||
|
||||
An invariant is a statement that stays true before and after every iteration.
|
||||
|
||||
For sliding window, the invariant often looks like one of these:
|
||||
|
||||
- "the current window is valid"
|
||||
- "the current window contains no duplicates"
|
||||
- "the current window sum is at most the target"
|
||||
- "the frequency map matches the characters currently inside the window"
|
||||
|
||||
The invariant gives the loop its structure:
|
||||
|
||||
- expand the window by moving right
|
||||
- update the window state
|
||||
- if the invariant breaks, shrink from the left until it holds again
|
||||
- update the answer only when you know the invariant is satisfied
|
||||
|
||||
|
||||
## Why Invariants Matter
|
||||
|
||||
Without an invariant, shrinking the window becomes arbitrary. You no longer know:
|
||||
|
||||
- when the window is valid
|
||||
- when to update the answer
|
||||
- why the left pointer should stop moving
|
||||
- The invariant is the reason the algorithm is correct.
|
||||
|
||||
## The Main Subtypes
|
||||
|
||||
### 1. Fixed-size windows
|
||||
|
||||
:::tip
|
||||
The window size never changes. The main task is updating the window state efficiently when one element enters and one leaves.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
### 2. Flexible-size windows with a validity rule
|
||||
|
||||
:::tip
|
||||
Here the window expands until invalid, then shrinks until valid again.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
|
||||
### 3. Frequency-tracking windows
|
||||
|
||||
:::tip
|
||||
The difficulty comes from keeping the bookkeeping correct as characters enter and leave.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
## How Sliding Window Differs From Other Two-Pointer Families
|
||||
|
||||
Compare it with Container With Most Water:
|
||||
|
||||
- In sliding window, the interval itself has meaning.
|
||||
- In container, the interval is just the remaining search space.
|
||||
|
||||
Compare it with Remove Duplicates:
|
||||
|
||||
- In sliding window, both pointers describe a live window.
|
||||
- In compaction, the left part of the array is already the answer prefix.
|
||||
|
||||
## A Practical Template
|
||||
|
||||
A common variable-size sliding window has this shape:
|
||||
|
||||
1. Add the new rightmost element.
|
||||
2. Update the window state.
|
||||
3. While the invariant is broken, remove elements from the left.
|
||||
4. Once the invariant is restored, update the answer.
|
||||
|
||||
The exact data structure changes from problem to problem, but the logic stays the same.
|
||||
|
||||
As you work through this section, keep asking:
|
||||
|
||||
:::warning
|
||||
What invariant does my window maintain, and at what moment is it safe to update the answer?
|
||||
:::
|
||||
Reference in new issue
Block a user