docs(docs): add meta files and reorganize topics with updated badges and directory structure

This commit is contained in:
Prad Nukala committed 2026-09-21 17:16:10 -04:00
1 parent f9e69960c4
commit 7c5061dcd1
66 files changed
+246 -46

No files matched your search

@@ -0,0 +1,60 @@
---
title: '121. Best Time to Buy and Sell Stock'
description: You are given an array prices where prices[i] is the price of a given stock on the i^th day
sidebar:
label: 'Best Time to Buy and Sell Stock'
badge: 'Easy'
---
<Badge variant="accent">Array</Badge>
### Example 1:
- Input: `prices = [7,1,5,3,6,4]`
- Output: `5`
- Explanation: Buy on day `2` (price = `1`) and sell on day `5` (price = `6`), profit = `6-1 = 5`. Note that buying on day `2` and selling on day `1` is not allowed because you must buy before you sell.
### Example 2:
- Input: `prices = [7,6,4,3,1]`
- Output: `0`
- Explanation: In this case, no transactions are done and the max profit = `0`.
### Constraints:
- `1 <= prices.length <= 10^5`
- `0 <= prices[i] <= 10^4`
## Approach
::::warning
The diagram traces the code below literally. That code does not run: `curr` and `ans` are never initialised, so the first `curr > left` test raises `NameError`, and `left` holds a price rather than an index, so `prices[left]` indexes by value.
::::
```mermaid
flowchart TD
S(["maxProfit(prices)"]) --> I["left = min(prices)"]
I --> F{"more right in range(len(prices))?"}
F -- no --> E(["return ans"])
F -- yes --> W{"curr > left?"}
W -- yes --> P["curr -= prices[left]; left += 1"]
P --> W
W -- no --> M["ans = max(ans, curr)"]
M --> F
```
## Solution
```py
class Solution:
def maxProfit(self, prices: List[int]) -> int:
left = min(prices)
for right in range(len(prices)):
while curr > left:
curr -= prices[left]
left += 1
ans = max(ans, curr)
return ans
```
## Explanation
<YouTube id="1pkOgXD63yU" title="Sliding Window: Best Time to Buy and Sell Stock - Leetcode 121 - Python" />
@@ -0,0 +1,66 @@
---
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">Hash Table</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.
## Approach
```mermaid
flowchart TD
S(["lengthOfLongestSubstring(s)"]) --> I["left = 0, ans = 0, window = set()"]
I --> L{"more (right, c) in s?"}
L -- no --> E(["return ans"])
L -- yes --> W{"c already in window?"}
W -- yes --> P["window.remove(s[left]); left += 1 — shrink until c is free"]
P --> W
W -- no --> A["window.add(c)"]
A --> M["ans = max(ans, right - left + 1)"]
M --> L
```
## Solution
```py
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left = 0
ans = 0
window = set()
for right, c in enumerate(s):
while c in window:
window.remove(s[left])
left += 1
window.add(c)
ans = max(ans, right - left + 1)
return ans
```
## Explanation
<YouTube id="wiGpQwVHdE0" title="Longest Substring Without Repeating Characters - Leetcode 3 - Python" />
@@ -0,0 +1,66 @@
---
title: '424. Longest Repeating Character Replacement'
description: You are given a string s and an integer k. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most k times
sidebar:
label: 'Longest Repeating Character Replacement'
badge: 'Medium'
---
<Badge variant="accent">Hash Table</Badge>
### Example 1:
- Input: `s = "ABAB", k = 2`
- Output: `4`
- Explanation: Replace the two 'A's with two 'B's or vice versa.
### Example 2:
- Input: `s = "AABABBA", k = 1`
- Output: `4`
- Explanation: Replace the one 'A' in the middle with 'B' and form "AABBBBA". The substring "BBBB" has the longest repeating letters, which is `4`. There may exists other ways to achieve this answer too.
### Constraints:
- `1 <= s.length <= 10^5`
- `s` consists of only uppercase English letters.
- `0 <= k <= s.length`
## Approach
```mermaid
flowchart TD
S(["characterReplacement(s, k)"]) --> I["count = {}, res = 0, l = 0, maxF = 0"]
I --> L{"more (r, c) in s?"}
L -- no --> E(["return res"])
L -- yes --> A["count[c] += 1; maxF = max(maxF, count[c])"]
A --> W{"(r - l + 1) - maxF > k? — too many chars to replace"}
W -- yes --> P["count[s[l]] -= 1; l += 1 — shrink from the left"]
P --> W
W -- no --> M["res = max(res, r - l + 1)"]
M --> L
```
## Solution
```py
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
count = {}
res = 0
l = 0
maxF = 0
for r, c in enumerate(s):
count[c] = 1 + count.get(c, 0)
maxF = max(maxF, count[c])
while (r - l + 1) - maxF > k:
count[s[l]] -= 1
l += 1
res = max(res, r - l + 1)
return res
```
## Explanation
<YouTube id="gqXU1UyA8pk" title="Longest Repeating Character Replacement - Leetcode 424 - Python" />
@@ -0,0 +1,73 @@
---
title: '567. Permutation in String'
description: Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise
sidebar:
label: 'Permutation in String'
badge: 'Medium'
---
<Badge variant="accent">Hash Table</Badge>
### Example 1:
- Input: `s1 = "ab", s2 = "eidbaooo"`
- Output: `true`
- Explanation: `s2` contains one permutation of `s1` ("ba").
### Example 2:
- Input: `s1 = "ab", s2 = "eidboaoo"`
- Output: `false`
### Constraints:
- `1 <= s1.length, s2.length <= 10^4`
- `s1` and `s2` consist of lowercase English letters.
## Approach
```mermaid
flowchart TD
S(["checkInclusion(s1, s2)"]) --> G{"k = len(s1) > len(s2)?"}
G -- yes --> X(["return False"])
G -- no --> I["need = Counter(s1), window = Counter()"]
I --> L{"more (right, c) in s2?"}
L -- no --> E(["return False"])
L -- yes --> A["window[c] += 1"]
A --> B{"right >= k? — window is now longer than k"}
B -- yes --> C["drop s2[right - k] from window, deleting the key at 0"]
B -- no --> Q
C --> Q{"window == need?"}
Q -- yes --> R(["return True"])
Q -- no --> L
```
## Solution
```py
from collections import Counter
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
k = len(s1)
if k > len(s2):
return False
need = Counter(s1)
window = Counter()
for right, c in enumerate(s2):
window[c] += 1
if right >= k:
left_char = s2[right - k]
window[left_char] -= 1
if window[left_char] == 0:
del window[left_char]
if window == need:
return True
return False
```
## Explanation
<YouTube id="UbyhOgBN834" title="Permutation in String - Leetcode 567 - Python" />
@@ -0,0 +1,104 @@
---
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.'
hidden: true
---
:::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.
:::
![Sliding Window Fixed Size](../../public/sliding-window-fixed-size.svg)
### 2. Flexible-size windows with a validity rule
:::tip
Here the window expands until invalid, then shrinks until valid again.
:::
![Flexible-size windows](../../public/sliding-window-flexible.svg)
### 3. Frequency-tracking windows
:::tip
The difficulty comes from keeping the bookkeeping correct as characters enter and leave.
:::
![Frequency-tracking windows](../../public/sliding-window-frequency.svg)
## 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?
:::
@@ -0,0 +1,3 @@
import { defineMeta } from "blume";
export default defineMeta({ title: "Sliding Window", order: 4 });