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
1 change: 1 addition & 0 deletions 300_longest_increasing_subsequence/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## 問題: [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/description/)
27 changes: 27 additions & 0 deletions 300_longest_increasing_subsequence/step1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Step 1

- 漸化式を作れなかった
- [NeetCode](https://www.youtube.com/watch?v=cjWnW0hdF1Y)の解法を見た
- LIS[i] を「nums[i] から始まる最長増加部分列の長さ」と定義する
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ある長さの最長増加部分列の末尾の値の最小値を考えることにより、 O(n log n) で解くこともできます。ほかの方の解答を参照されるとよいと思います。

- 各要素単体でも部分列なので、初期値をすべて 1 にする
- 後ろから順に各 index i を処理する
- i より右側の要素 j を見て、nums[i] < nums[j] なら連結可能
- 連結できる場合、LIS[i] = max(LIS[i], 1 + LIS[j]) で更新する
- 最後に LIS 配列の最大値を返す

```python
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
LIS = [1] * len(nums)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LIS という名前は定数っぽく感じます。 i 番目の数字で終わる最長増加部分列の長さの最大値が格納されますので、 tail_index_to_max_length はいかがでしょうか?


for i in range(len(nums) - 1, -1, -1):
for j in range(len(nums) - 1, i, -1):
if nums[i] < nums[j]:
LIS[i] = max(LIS[i], 1 + LIS[j])

return max(LIS)
```

時間計算量: $O(n^2)$

空間計算量: $O(n)$
19 changes: 19 additions & 0 deletions 300_longest_increasing_subsequence/step2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Step 2

```python
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
lis_from_i = [1] * len(nums)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

格納されるのが最大の長さのため、 lis とするのは、中身と名前がずれているように思いました。


for i in range(len(nums) - 1, -1, -1):
for j in range(len(nums) - 1, i, -1):
if nums[i] < nums[j]:
lis_from_i[i] = max(lis_from_i[i], 1 + lis_from_i[j])

return max(lis_from_i)

```

時間計算量: $O(n^2)$

空間計算量: $O(n)$
21 changes: 21 additions & 0 deletions 300_longest_increasing_subsequence/step3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Step 3

```python
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
lis_from_i = [1] * len(nums)

for i in range(len(nums) - 1, -1, -1):
for j in range(len(nums) - 1, i, -1):
if nums[i] < nums[j]:
lis_from_i[i] = max(lis_from_i[i], 1 + lis_from_i[j])

return max(lis_from_i)

```

1回目: 1分 17秒

2回目: 1分 23秒

3回目: 1分 14秒