-
Notifications
You must be signed in to change notification settings - Fork 0
Solved: 300. Longest Increasing Subsequence #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| ## 取り組み方 | ||
| - step1: 5分以内に空で書いてAcceptedされるまで解く + テストケースと関連する知識を連想してみる | ||
| - step2: 他の方の記録を読んで連想すべき知識や実装を把握した上で、前提を置いた状態で最適な手法を選択し実装する | ||
| - step3: 10分以内に1回もエラーを出さずに3回連続で解く | ||
|
|
||
| ## step1 | ||
| `nums[index]`を使用したときのLISを`length_LIS[index]`とする | ||
|
|
||
| ある`index`とその`index`よりも前の`former_index`について、 | ||
| `nums[former_index] < nums[index]`の時、`length_LIS[former_index] + 1`が`length_LIS[index]`の候補となる。 | ||
| これを一通りみていって、`length_LIS`を更新していって最大のものが答えとなる。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def lengthOfLIS(self, nums: List[int]) -> int: | ||
| length_nums = len(nums) | ||
| length_LIS = [1] * length_nums | ||
|
|
||
| for index in range(1, length_nums): | ||
| for former_index in range(index): | ||
| if nums[index] > nums[former_index]: | ||
| length_LIS[index] = max( | ||
| length_LIS[index], | ||
| length_LIS[former_index] + 1 | ||
| ) | ||
| return max(length_LIS) | ||
| ``` | ||
|
|
||
| ## step2 | ||
| ### 読んだコード | ||
| - https://github.com/fuga-98/arai60/pull/31/files | ||
| - https://github.com/sakupan102/arai60-practice/pull/32/files | ||
| - https://github.com/hayashi-ay/leetcode/pull/27/files | ||
|
|
||
| ### 感想 | ||
| - numsをはじめから見ていって、各長さのLISにおける末尾の最小値を保持するやり方もあった | ||
| - 発想も素直な気がするのでこれは思いついても良さそうだった | ||
| - ついでに`bisect_left`の実装をみたが、変数名が雑すぎるなあ | ||
| - https://github.com/python/cpython/blob/3.13/Lib/bisect.py#L74 | ||
| - 一方、末尾の最小値を保持していくやり方は、最終的なLIS自体を返してくれと追加の要件が出てきたときに編集しにくそうなので、動的計画法で実装する方が良さそう | ||
| - `segment tree`と座標圧縮を利用した解法もあるみたいだが、常識から外れそうなので一旦スキップする | ||
| - `LIS`は小文字でも良さそう | ||
|
|
||
| #### 動的計画法 | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLIS(self, nums: List[int]) -> int: | ||
| length_lis = [1] * len(nums) | ||
| for index in range(len(nums)): | ||
| for former_index in range(index): | ||
| if nums[index] > nums[former_index]: | ||
| length_lis[index] = max( | ||
| length_lis[index], | ||
| length_lis[former_index] + 1 | ||
| ) | ||
| return max(length_lis) | ||
| ``` | ||
|
|
||
| #### 二分探索 | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLIS(self, nums: List[int]) -> int: | ||
| # tails: 各長さの増加部分列における最小の末尾値を保持するリスト | ||
| tails = [] | ||
| for num in nums: | ||
| insertion_position = bisect_left(tails, num) | ||
| if insertion_position == len(tails): | ||
| tails.append(num) | ||
| else: | ||
| tails[insertion_position] = num | ||
|
Comment on lines
+67
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私は、唐突にこれを逆にしたほうが素直かなと思いましたが if insertion_position < len(tails):
tails[insertion_position] = num
else:
tails.append(num)趣味の範囲です。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. レビューありがとうございます。 |
||
| return len(tails) | ||
| ``` | ||
|
|
||
| ## step3 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def lengthOfLIS(self, nums: List[int]) -> int: | ||
| length_lis = [1] * len(nums) | ||
| for index in range(len(nums)): | ||
| for former_index in range(index): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 趣味だと思いますが、ここを関数にしたほうがより分かりやすくなると思います。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. レビューありがとうございます。 見返してみると、 |
||
| if nums[index] > nums[former_index]: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ネスト深めなので、早期continueしたい気もします。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. すみません。コメント見逃しておりました。 |
||
| length_lis[index] = max( | ||
| length_lis[index], length_lis[former_index] + 1) | ||
| return max(length_lis) | ||
| ``` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstringをきちんと書いているからOKなんですかね。