Skip to content

Commit

Permalink
add more dp and monotatic stack
Browse files Browse the repository at this point in the history
  • Loading branch information
afeish committed Mar 16, 2024
1 parent 9569128 commit dda1afe
Show file tree
Hide file tree
Showing 7 changed files with 645 additions and 0 deletions.
282 changes: 282 additions & 0 deletions _data/monotonic-stack.drawio

Large diffs are not rendered by default.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
layout: single
title: "Longest Palindromic Subsequence"
date: 2024-03-15 20:48:54 +0800
categories: algo
tags: dp leetcode dfs
collection: 2024
classes: wide

toc: true
toc_label: "Content Outline"
toc_icon: "cog"
toc_sticky: true

---

## [2246. Longest Path With Different Adjacent Characters](https://leetcode.com/problems/longest-path-with-different-adjacent-characters/)

You are given a **tree** (i.e. a connected, undirected graph that has no cycles) **rooted** at node `0` consisting of `n` nodes numbered from `0` to `n - 1`. The tree is represented by a **0-indexed** array `parent` of size `n`, where `parent[i]` is the parent of node `i`. Since node `0` is the root, `parent[0] == -1`.

You are also given a string `s` of length `n`, where `s[i]` is the character assigned to node `i`.

Return *the length of the **longest path** in the tree such that no pair of **adjacent** nodes on the path have the same character assigned to them.*



**Example 1:**

![img](https://assets.leetcode.com/uploads/2022/03/25/testingdrawio.png)

```
Input: parent = [-1,0,0,1,1,2], s = "abacbe"
Output: 3
Explanation: The longest path where each two adjacent nodes have different characters in the tree is the path: 0 -> 1 -> 3. The length of this path is 3, so 3 is returned.
It can be proven that there is no longer path that satisfies the conditions.
```

**Example 2:**

![img](https://assets.leetcode.com/uploads/2022/03/25/graph2drawio.png)

```
Input: parent = [-1,0,0,0], s = "aabc"
Output: 3
Explanation: The longest path where each two adjacent nodes have different characters is the path: 2 -> 0 -> 3. The length of this path is 3, so 3 is returned.
```



**Constraints:**

- `n == parent.length == s.length`
- `1 <= n <= 105`
- `0 <= parent[i] <= n - 1` for all `i >= 1`
- `parent[0] == -1`
- `parent` represents a valid tree.
- `s` consists of only lowercase English letters.


## Solutions



```py
class Solution:
def longestPath(self, parent: List[int], s: str) -> int:
n = len(parent)
g = [[] for _ in range(n)]
for i in range(1, n):
g[parent[i]].append(i)

ans = 0
def dfs(x, fa):
nonlocal ans
x_len = 0
for y in g[x]:
if y == fa: continue
y_len = dfs(y, x) + 1
if s[y] != s[x]:
ans = max(ans, x_len + y_len)
x_len = max(x_len, y_len)
return x_len
dfs(0, -1)
return ans + 1
```

Input: parent = [-1,0,0,1,1,2], s = "abacbe"

output:

```shell
3
```

#### Complexity

- Time complexity: ( O(n) ), where ( n ) is the length of the array.
- Space complexity: ( O(n) ), where ( n) is the length of the array.
131 changes: 131 additions & 0 deletions _posts/2024-03-15-Trapping-Rain-Water.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
layout: single
title: "Trapping Rain Water"
date: 2024-03-15 20:48:54 +0800
categories: algo
tags: leetcode stack monotonic-stack prefix-sum
collection: 2024
classes: wide

toc: true
toc_label: "Content Outline"
toc_icon: "cog"
toc_sticky: true

---

## [42. Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/)
Given `n` non-negative integers representing an elevation map where the width of each bar is `1`, compute how much water it can trap after raining.



**Example 1:**

![img](https://assets.leetcode.com/uploads/2018/10/22/rainwatertrap.png)

```
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
```

**Example 2:**

```
Input: height = [4,2,0,3,2,5]
Output: 9
```



**Constraints:**

- `n == height.length`

- `1 <= n <= 2 * 104`

- `0 <= height[i] <= 105`



## Analysis

We can use the monotonic stack to resolve the problem. We use a stack named `s` which store the unresolved index,

1. we compare the current height `height[i]` with the top of stack `s[-1]`. If `height[i] > s[-1]`, it means we cound find a target trap, we can pop the index from the stack twice and calculate the trap area; then continue the next round until one of bellow condition meet:
1. The stack is empty
2. The height of stack's top is bigger than `height[i]`
2. If it's less, then we should just push the current index.

![img](/assets/images/trapping-water.drawio.svg)

## Solutions



### 1. Monotanic-Stack

```py
class Solution:
def trap(self, height: List[int]) -> int:
s = []

ans = 0
for i, h in enumerate(height):
while s and h >= height[s[-1]]:
b_h = height[s.pop()]
if not s:
break
left = s[-1]
dh = (min(h, height[left])) - b_h
ans += dh * (i-left-1)
s.append(i)
return ans
```

Input: `[0,1,0,2,1,0,1,3,2,1,2,1]`

output:

```shell
6
```

#### Complexity

- Time complexity: ( O(n) ), where ( n ) is the length of the array.
- Space complexity: ( O(n) ), where ( n) is the length of the array.

### 2. Prefix-Sum

```python
class Solution:
def trap(self, height: List[int]) -> int:
n = len(height)
pre_max = [0] * n
pre_max[0] = height[0]
for i in range(1, n):
pre_max[i] = max(pre_max[i-1], height[i])
suf_max = [0] * n
suf_max[-1] = height[-1]
for i in range(n-2, -1, -1):
suf_max[i] = max(suf_max[i+1], height[i])
ans = 0
for h, pre, suf in zip(height, pre_max, suf_max):
ans += min(pre, suf) - h

return ans
```

Input: `[0,1,0,2,1,0,1,3,2,1,2,1]`

output:

```shell
6
```

#### Complexity

- Time complexity: ( O(n) ), where ( n ) is the length of the array.
- Space complexity: ( O(n) ), where ( n) is the length of the array.
126 changes: 126 additions & 0 deletions _posts/2024-03-15-daily-temperatures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
layout: single
title: "Daily Temperatures"
date: 2024-03-15 20:48:54 +0800
categories: algo
tags: leetcode stack monotonic-stack
collection: 2024
classes: wide

toc: true
toc_label: "Content Outline"
toc_icon: "cog"
toc_sticky: true

---

## [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/)

Given an array of integers `temperatures` represents the daily temperatures, return *an array* `answer` *such that* `answer[i]` *is the number of days you have to wait after the* `ith` *day to get a warmer temperature*. If there is no future day for which this is possible, keep `answer[i] == 0` instead.



**Example 1:**

```
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]
```

**Example 2:**

```
Input: temperatures = [30,40,50,60]
Output: [1,1,1,0]
```

**Example 3:**

```
Input: temperatures = [30,60,90]
Output: [1,1,0]
```



**Constraints:**

- `1 <= temperatures.length <= 105`
- `30 <= temperatures[i] <= 100`

## Analysis

We can use the monotonic stack to resolve the problem. We use a stack named `s` which store the unresolved index,

1. we check the current temperature `temperature[i]` with the top of stack `s[-1]`. If `temperature[i] > s[-1]`, it means we found the target temperature, we can pop the index from the stack and mark that index as resolved; then continue the next round until one of bellow condition meet:
1. The stack is empty
2. The temperature poped is bigger than `temperature[i]`
2. If it's less, then we should just push the current index.

![img](/assets/images/monotonic-stack.drawio.svg)

## Solutions



### 1. From left to right

```py
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
n = len(temperatures)
s = []
ans = [0] * n
for i in range(n):
t = temperatures[i]
while s and t > temperatures[s[-1]]:
j = s.pop()
ans[j] = i - j
s.append(i)
return ans

```

Input: `"bbbab"`

output:

```shell
4
```

#### Complexity

- Time complexity: ( O(n) ), where ( n ) is the length of the array.
- Space complexity: ( O(n) ), where ( n) is the length of the array.

### 2. From right to left

```python
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
n = len(temperatures)
s = []
ans = [0] * n
for i in range(n-1,-1,-1):
t = temperatures[i]
while s and t >= temperatures[s[-1]]:
s.pop()
if s:
ans[i] = s[-1] - i
s.append(i)
return ans
```

Input: `"bbbab"`

output:

```shell
4
```

#### Complexity

- Time complexity: ( O(n) ), where ( n ) is the length of the array.
- Space complexity: ( O(n) ), where ( n) is the length of the array.
4 changes: 4 additions & 0 deletions assets/images/monotonic-stack.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions assets/images/trapping-water.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit dda1afe

Please sign in to comment.