mirror of
https://github.com/Rainyy21/framework_note.git
synced 2026-10-11 01:10:28 -04:00
vault backup: 2026-06-05 18:15:42
This commit is contained in:
@@ -6,8 +6,86 @@ tags:
|
||||
- hash-table
|
||||
- string
|
||||
- sorting
|
||||
status: unsolve
|
||||
date_solved: 2026-05-26
|
||||
status: Solved
|
||||
date_solved: 2026-06-05
|
||||
leetcode_url: https://leetcode.com/problems/valid-anagram/
|
||||
review_needed: false
|
||||
---
|
||||
|
||||
# 242. Valid Anagram
|
||||
|
||||
> [!info] **Problem Link**: [LeetCode - Valid Anagram](https://leetcode.com/problems/valid-anagram/)
|
||||
|
||||
## 📝 Problem Description
|
||||
|
||||
Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.
|
||||
|
||||
An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
|
||||
|
||||
---
|
||||
|
||||
### 📥 Example 1
|
||||
> **Input:** `s = "anagram"`, `t = "nagaram"`
|
||||
> **Output:** `true`
|
||||
|
||||
### 📥 Example 2
|
||||
> **Input:** `s = "rat"`, `t = "car"`
|
||||
> **Output:** `false`
|
||||
|
||||
---
|
||||
|
||||
## 💡 Approaches & Explanations
|
||||
|
||||
### Approach 1: Hash Map (Frequency Counter) — *Optimal*
|
||||
Since an anagram must have the exact same characters with the same frequencies, we can use a hash map (or a fixed-size array for lowercase English letters) to count the occurrences of each character in both strings.
|
||||
1. If the lengths of `s` and `t` are different, they cannot be anagrams.
|
||||
2. Count the frequency of each character in `s`.
|
||||
3. Decrement the frequency for each character in `t`.
|
||||
4. If all counts return to zero, the strings are anagrams.
|
||||
|
||||
#### 📊 Complexity Analysis
|
||||
- **Time Complexity:** $\mathcal{O}(N)$ where $N$ is the length of the strings. We iterate through each string once.
|
||||
- **Space Complexity:** $\mathcal{O}(1)$ because the size of the hash map is limited by the number of unique characters in the alphabet (e.g., 26 for lowercase English letters).
|
||||
|
||||
---
|
||||
|
||||
### Approach 2: Sorting
|
||||
If we sort both strings, two anagrams will result in the same identical string.
|
||||
- **Time Complexity:** $\mathcal{O}(N \log N)$ due to sorting.
|
||||
- **Space Complexity:** $\mathcal{O}(1)$ or $\mathcal{O}(N)$ depending on whether the language allows in-place string sorting or requires converting the string to a list.
|
||||
|
||||
---
|
||||
|
||||
## 💻 Code Implementations
|
||||
|
||||
### Python3
|
||||
```python
|
||||
class Solution:
|
||||
def isAnagram(self, s: str, t: str) -> bool:
|
||||
if len(s) != len(t):
|
||||
return False
|
||||
|
||||
count = {}
|
||||
for char in s:
|
||||
count[char] = count.get(char, 0) + 1
|
||||
|
||||
for char in t:
|
||||
if char not in count or count[char] == 0:
|
||||
return False
|
||||
count[char] -= 1
|
||||
|
||||
return True
|
||||
|
||||
# Alternative using collections.Counter
|
||||
from collections import Counter
|
||||
class Solution2:
|
||||
def isAnagram(self, s: str, t: str) -> bool:
|
||||
return Counter(s) == Counter(t)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Key Takeaways & Lessons
|
||||
- **Character Counting:** For problems involving permutations or character frequency, a hash map or an array of size 26 is often the most efficient tool.
|
||||
- **Early Exit:** Always check for length differences first to save time in edge cases.
|
||||
- **Sorting as a Normalization:** Sorting is a powerful way to "normalize" data to check for equivalence in different orderings, though it is often slightly less efficient than counting.
|
||||
|
||||
@@ -5,8 +5,86 @@ difficulty: Easy
|
||||
tags:
|
||||
- hash-table
|
||||
- string
|
||||
status: unsolve
|
||||
date_solved: 2026-05-26
|
||||
status: Solved
|
||||
date_solved: 2026-06-05
|
||||
leetcode_url: https://leetcode.com/problems/word-pattern/
|
||||
review_needed: false
|
||||
---
|
||||
|
||||
# 290. Word Pattern
|
||||
|
||||
> [!info] **Problem Link**: [LeetCode - Word Pattern](https://leetcode.com/problems/word-pattern/)
|
||||
|
||||
## 📝 Problem Description
|
||||
|
||||
Given a `pattern` and a string `s`, find if `s` follows the same pattern.
|
||||
|
||||
Here **follow** means a full match, such that there is a bijection between a letter in `pattern` and a non-empty word in `s`.
|
||||
|
||||
---
|
||||
|
||||
### 📥 Example 1
|
||||
> **Input:** `pattern = "abba"`, `s = "dog cat cat dog"`
|
||||
> **Output:** `true`
|
||||
|
||||
### 📥 Example 2
|
||||
> **Input:** `pattern = "abba"`, `s = "dog cat cat fish"`
|
||||
> **Output:** `false`
|
||||
|
||||
### 📥 Example 3
|
||||
> **Input:** `pattern = "aaaa"`, `s = "dog cat cat dog"`
|
||||
> **Output:** `false`
|
||||
|
||||
---
|
||||
|
||||
## 💡 Approaches & Explanations
|
||||
|
||||
### Approach 1: Two Hash Maps (Bijective Mapping) — *Optimal*
|
||||
To ensure a bijection (one-to-one mapping) between characters in `pattern` and words in `s`, we need to verify two things:
|
||||
1. Every character in `pattern` maps to exactly one word in `s`.
|
||||
2. Every word in `s` maps to exactly one character in `pattern`.
|
||||
|
||||
Using two hash maps allows us to track these mappings in both directions. Alternatively, we can use one hash map for the mapping and a set to ensure the values are unique.
|
||||
|
||||
#### 📊 Complexity Analysis
|
||||
- **Time Complexity:** $\mathcal{O}(N + M)$ where $N$ is the number of characters in the pattern and $M$ is the number of characters in string `s`. We split the string and then iterate through the pattern.
|
||||
- **Space Complexity:** $\mathcal{O}(W)$ where $W$ is the number of unique words in `s` and unique characters in `pattern`.
|
||||
|
||||
---
|
||||
|
||||
## 💻 Code Implementations
|
||||
|
||||
### Python3
|
||||
```python
|
||||
class Solution:
|
||||
def wordPattern(self, pattern: str, s: str) -> bool:
|
||||
words = s.split()
|
||||
|
||||
if len(pattern) != len(words):
|
||||
return False
|
||||
|
||||
char_to_word = {}
|
||||
word_to_char = {}
|
||||
|
||||
for char, word in zip(pattern, words):
|
||||
if char in char_to_word:
|
||||
if char_to_word[char] != word:
|
||||
return False
|
||||
else:
|
||||
char_to_word[char] = word
|
||||
|
||||
if word in word_to_char:
|
||||
if word_to_char[word] != char:
|
||||
return False
|
||||
else:
|
||||
word_to_char[word] = char
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Key Takeaways & Lessons
|
||||
- **Bijective Mapping:** When a problem requires a 1-to-1 relationship, remember that a single hash map only tracks the mapping in one direction. You must either use two maps or check that the values in the single map are unique.
|
||||
- **String Splitting:** Python's `.split()` defaults to splitting by any whitespace, which is perfect for space-separated word problems.
|
||||
- **Zip for Parallel Iteration:** The `zip()` function is an idiomatic way to iterate over two sequences simultaneously.
|
||||
|
||||
@@ -5,8 +5,96 @@ difficulty: Easy
|
||||
tags:
|
||||
- array
|
||||
- prefix-sum
|
||||
status: unsolve
|
||||
date_solved: 2026-05-26
|
||||
status: Solved
|
||||
date_solved: 2026-06-05
|
||||
leetcode_url: https://leetcode.com/problems/find-pivot-index/
|
||||
review_needed: false
|
||||
---
|
||||
|
||||
# 724. Find Pivot Index
|
||||
|
||||
> [!info] **Problem Link**: [LeetCode - Find Pivot Index](https://leetcode.com/problems/find-pivot-index/)
|
||||
|
||||
## 📝 Problem Description
|
||||
|
||||
Given an array of integers `nums`, calculate the **pivot index** of this array.
|
||||
|
||||
The **pivot index** is the index where the sum of all the numbers strictly to the left of the index is equal to the sum of all the numbers strictly to the right of the index.
|
||||
|
||||
If the index is on the left edge of the array, then the left sum is `0` because there are no elements to the left. This also applies to the right edge of the array.
|
||||
|
||||
Return the *leftmost pivot index*. If no such index exists, return `-1`.
|
||||
|
||||
---
|
||||
|
||||
### 📥 Example 1
|
||||
> **Input:** `nums = [1,7,3,6,5,6]`
|
||||
> **Output:** `3`
|
||||
> **Explanation:**
|
||||
> The pivot index is 3.
|
||||
> Left sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11
|
||||
> Right sum = nums[4] + nums[5] = 5 + 6 = 11
|
||||
|
||||
### 📥 Example 2
|
||||
> **Input:** `nums = [1,2,3]`
|
||||
> **Output:** `-1`
|
||||
> **Explanation:**
|
||||
> There is no index that satisfies the conditions in the problem statement.
|
||||
|
||||
### 📥 Example 3
|
||||
> **Input:** `nums = [2,1,-1]`
|
||||
> **Output:** `0`
|
||||
> **Explanation:**
|
||||
> The pivot index is 0.
|
||||
> Left sum = 0 (no elements to the left of index 0)
|
||||
> Right sum = nums[1] + nums[2] = 1 + (-1) = 0
|
||||
|
||||
---
|
||||
|
||||
## 💡 Approaches & Explanations
|
||||
|
||||
### Approach 1: Prefix Sum — *Optimal*
|
||||
The key insight is that for any index `i`, we can determine the `right_sum` if we know the `total_sum` and the `left_sum`.
|
||||
Specifically: `right_sum = total_sum - left_sum - nums[i]`.
|
||||
The condition for `i` being a pivot index is `left_sum == right_sum`, which simplifies to:
|
||||
`left_sum == total_sum - left_sum - nums[i]`
|
||||
or
|
||||
`2 * left_sum + nums[i] == total_sum`.
|
||||
|
||||
1. Calculate the `total_sum` of the array.
|
||||
2. Initialize `left_sum = 0`.
|
||||
3. Iterate through the array. At each index `i`:
|
||||
- Check if the condition `left_sum == total_sum - left_sum - nums[i]` holds.
|
||||
- If yes, return `i`.
|
||||
- Update `left_sum += nums[i]`.
|
||||
4. If the loop finishes without returning, return `-1`.
|
||||
|
||||
#### 📊 Complexity Analysis
|
||||
- **Time Complexity:** $\mathcal{O}(N)$ where $N$ is the number of elements in `nums`. We traverse the array twice (once for the total sum, once for the search).
|
||||
- **Space Complexity:** $\mathcal{O}(1)$ as we only use a few variables for sums.
|
||||
|
||||
---
|
||||
|
||||
## 💻 Code Implementations
|
||||
|
||||
### Python3
|
||||
```python
|
||||
class Solution:
|
||||
def pivotIndex(self, nums: List[int]) -> int:
|
||||
total_sum = sum(nums)
|
||||
left_sum = 0
|
||||
|
||||
for i, num in enumerate(nums):
|
||||
if left_sum == (total_sum - left_sum - num):
|
||||
return i
|
||||
left_sum += num
|
||||
|
||||
return -1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Key Takeaways & Lessons
|
||||
- **Equation Simplification:** Many "equilibrium" or "pivot" problems can be solved by expressing the "right side" in terms of the "total" and the "left side," reducing the need for multiple passes or extra space.
|
||||
- **Prefix Sum Pattern:** This is a classic application of the prefix sum concept, where we maintain a running total to answer queries or check conditions in $\mathcal{O}(1)$ time per element.
|
||||
- **Handling Edge Cases:** The problem explicitly defines sum at edges as 0, which is naturally handled by starting `left_sum` at 0 and checking the condition before updating it.
|
||||
|
||||
Reference in New Issue
Block a user