Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ impl Solution {
### Time & Space Complexity

- Time complexity: $O(n ^ 2)$
- Space complexity: $O(n)$
- Space complexity: $O(n ^ 2)$ in the worst case due to copied subarrays; the recursion stack alone is $O(n)$.

---

Expand Down
6 changes: 3 additions & 3 deletions articles/clone-graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Before attempting this problem, you should be comfortable with:

---

## 1. Depth First Seacrh
## 1. Depth First Search

### Intuition
The graph may contain **cycles**, so we cannot simply copy nodes recursively without remembering what we've already copied.
Expand Down Expand Up @@ -130,11 +130,11 @@ public:
class Solution {
public:
Node* cloneGraph(Node* node) {
map<Node*, Node*> oldToNew;
unordered_map<Node*, Node*> oldToNew;
return dfs(node, oldToNew);
}

Node* dfs(Node* node, map<Node*, Node*>& oldToNew) {
Node* dfs(Node* node, unordered_map<Node*, Node*>& oldToNew) {
if (node == nullptr) {
return nullptr;
}
Expand Down
8 changes: 4 additions & 4 deletions articles/is-anagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,10 +375,10 @@ impl Solution {

### Time & Space Complexity

- Time complexity: $O(n + m)$
- Time complexity: $O(n)$
- Space complexity: $O(1)$ since we have at most $26$ different characters.

> Where $n$ is the length of string $s$ and $m$ is the length of string $t$.
> Where $n$ is the length of the strings after the early length check.

---

Expand Down Expand Up @@ -603,10 +603,10 @@ impl Solution {

### Time & Space Complexity

- Time complexity: $O(n + m)$
- Time complexity: $O(n)$
- Space complexity: $O(1)$ since we have at most $26$ different characters.

> Where $n$ is the length of string $s$ and $m$ is the length of string $t$.
> Where $n$ is the length of the strings after the early length check.

---

Expand Down
153 changes: 113 additions & 40 deletions articles/meeting-rooms-iii.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,13 @@ impl Solution {
}
}

meeting_count
.iter()
.enumerate()
.max_by_key(|&(_, &count)| count)
.unwrap()
.0 as i32
let mut max_room = 0;
for i in 1..n {
if meeting_count[i] > meeting_count[max_room] {
max_room = i;
}
}
max_room as i32
}
}
```
Expand Down Expand Up @@ -736,44 +737,110 @@ class Solution {
```

```swift
struct MinHeap<T> {
private var heap: [T] = []
private let areSorted: (T, T) -> Bool

init(_ areSorted: @escaping (T, T) -> Bool) {
self.areSorted = areSorted
}

var isEmpty: Bool {
heap.isEmpty
}

var peek: T? {
heap.first
}

mutating func push(_ value: T) {
heap.append(value)
siftUp(heap.count - 1)
}

mutating func pop() -> T? {
guard !heap.isEmpty else {
return nil
}
if heap.count == 1 {
return heap.removeLast()
}

let value = heap[0]
let last = heap.removeLast()
heap[0] = last
siftDown(0)
return value
}

private mutating func siftUp(_ index: Int) {
var child = index
var parent = (child - 1) / 2

while child > 0 && areSorted(heap[child], heap[parent]) {
heap.swapAt(child, parent)
child = parent
parent = (child - 1) / 2
}
}

private mutating func siftDown(_ index: Int) {
var parent = index

while true {
let left = 2 * parent + 1
let right = left + 1
var candidate = parent

if left < heap.count && areSorted(heap[left], heap[candidate]) {
candidate = left
}
if right < heap.count && areSorted(heap[right], heap[candidate]) {
candidate = right
}
if candidate == parent {
return
}

heap.swapAt(parent, candidate)
parent = candidate
}
}
}

class Solution {
func mostBooked(_ n: Int, _ meetings: [[Int]]) -> Int {
let meetings = meetings.sorted { $0[0] < $1[0] }
var available = Array(0..<n)
var used: [(end: Int64, room: Int)] = []
var count = [Int](repeating: 0, count: n)

func heapifyAvailable() {
available.sort()
var available = MinHeap<Int>(<)
var used = MinHeap<(end: Int64, room: Int)> {
if $0.end == $1.end {
return $0.room < $1.room
}
return $0.end < $1.end
}
var count = [Int](repeating: 0, count: n)

func heapifyUsed() {
used.sort { ($0.end, $0.room) < ($1.end, $1.room) }
for room in 0..<n {
available.push(room)
}

heapifyAvailable()

for meeting in meetings {
let start = Int64(meeting[0])
var end = Int64(meeting[1])

heapifyUsed()
while !used.isEmpty && used[0].end <= start {
let room = used.removeFirst().room
available.append(room)
heapifyAvailable()
while let earliest = used.peek, earliest.end <= start {
let room = used.pop()!.room
available.push(room)
}

if available.isEmpty {
heapifyUsed()
let current = used.removeFirst()
let current = used.pop()!
end = current.end + (end - start)
available.append(current.room)
heapifyAvailable()
available.push(current.room)
}

let room = available.removeFirst()
used.append((end: end, room: room))
let room = available.pop()!
used.push((end: end, room: room))
count[room] += 1
}

Expand Down Expand Up @@ -829,12 +896,13 @@ impl Solution {
count[room] += 1;
}

count
.iter()
.enumerate()
.max_by_key(|&(_, &c)| c)
.unwrap()
.0 as i32
let mut max_room = 0;
for i in 1..n {
if count[i] > count[max_room] {
max_room = i;
}
}
max_room as i32
}
}
```
Expand All @@ -843,7 +911,11 @@ impl Solution {

### Time & Space Complexity

- Time complexity: $O(m\log m + m \log n)$
- Time complexity: $O(m \log m + (m + n) \log n)$
- Sorting the meetings costs $O(m \log m)$.
- Initializing `available` by inserting `n` rooms one at a time is bounded by $O(n \log n)$.
- Across all meetings, heap operations cost $O(m \log n)$.
- The Python block starts with an already heap-ordered list, so its initialization is $O(n)$, but the shared bound above applies across the implementations.
- Space complexity: $O(n)$

> Where $n$ is the number of rooms and $m$ is the number of meetings.
Expand Down Expand Up @@ -1206,12 +1278,13 @@ impl Solution {
count[room] += 1;
}

count
.iter()
.enumerate()
.max_by_key(|&(_, &c)| c)
.unwrap()
.0 as i32
let mut max_room = 0;
for i in 1..n {
if count[i] > count[max_room] {
max_room = i;
}
}
max_room as i32
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion articles/search-for-word-ii.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ impl Solution {
if found { break; }
for c in 0..cols {
if board[r][c] != word_chars[0] { continue; }
if Self::backtrack(&mut board, r, c, &word_chars, 0) {
if Self::backtrack(&mut board, r as i32, c as i32, &word_chars, 0) {
res.push(word.clone());
found = true;
break;
Expand Down
2 changes: 1 addition & 1 deletion hints/is-anagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<details class="hint-accordion">
<summary>Recommended Time & Space Complexity</summary>
<p>
You should aim for a solution with <code>O(n + m)</code> time and <code>O(1)</code> space, where <code>n</code> is the length of the string <code>s</code> and <code>m</code> is the length of the string <code>t</code>.
You should aim for a solution with <code>O(n)</code> time and <code>O(1)</code> space, where <code>n</code> is the length of the strings after checking that their lengths are equal.
</p>
</details>

Expand Down