Skip to content

207. Course Schedule#3

Merged
thonda28 merged 6 commits intomainfrom
207.course-schedule
Apr 24, 2024
Merged

207. Course Schedule#3
thonda28 merged 6 commits intomainfrom
207.course-schedule

Conversation

@thonda28
Copy link
Copy Markdown
Owner

@thonda28 thonda28 commented Apr 22, 2024

Problem

Description

  • Step1
    • 13分30秒で解答
    • 時間計算量: O(V+E) 、空間計算量: O(V+E) ※ V = numCourses, E = len(prerequisites)
    • トポロジカルソートの実装を愚直にした
      • 他コースに依存しないコースから処理をしていき、新たに依存しないコースが出たら Stack に追加
      • while 文を抜けた後に、while 文で処理した course の数を数え、numCourses と一致すれば True(一致しない場合は Dead Lock が起きているため False)
    • テストケースの実行で以下が原因でエラー
      • while 文内の if course not in constraint_map: を書いていなかった
      • 単純な Typo
    • 命名が難しく、長い割に意味がわかりにくいものとなってしまった
  • Step2
    • データ構造
      • dict() を使ったことでコードがわかりにくくなっていそうだったので、list() を使うことでコードをシンプルに
      • トポロジカルソートの結果は不要なので、単純に処理が終わった course の数をカウント
    • 命名系
      • indegree(入次数)という用語があるようなので採用
      • course_i より後にしか受講できないものを表したいので postrequisites という言葉を採用(意味が正しいか不明だが)
        • postrequisites_of_courses[i] は「course_i の事後にしか受講できない courses」を意味しているつもり
      • from と to とかを使ってもよいかも?依存関係が明示的にはなりそう(ただ依存とはちょっとニュアンスが違うかもしれない)
  • Step3(追記:Stack で解いたものを再帰で書き直してみたもの、通常の Step3 とは異なる)
    • Step1 の段階で15分以内で解けているので Skip
    • while 文を再帰で書き直すよう整理
      • while 文で indegree=0 となったときに stack に積む代わりに再帰関数を呼ぶ
      • visited を入れ忘れていたことによるエラーの遭遇
      • 結果は indegree がすべて0かどうかでサイクルがないかを判断(途中でサイクルを検出する方法はわからず)

Note

  • 同じ問題を1年1ヶ月前に解いた経験あり
    • 当時はトポロジカルソート自体を知らず、解答を見て内容と実装方法を学習した記憶

Tomoya Honda added 2 commits April 22, 2024 12:55
@thonda28 thonda28 marked this pull request as ready for review April 22, 2024 14:05
Copy link
Copy Markdown

@nodchip nodchip left a comment

Choose a reason for hiding this comment

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

再帰関数を使った深さ優先探索でも書けますか?

# @lc code=start
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
constraint_map, num_of_constraint_map = dict(), dict()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

コードの読みやすさの観点からは、わざわざ 2 つの変数を同時に代入するメリットはないように思います。ただし、 2 つの変数をスワップする場合は、 2 つの変数を同時に代入する書き方のほうが分かりやすいと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。たしかにそうですね、「なんとなくまとめられそうだから」でこのようにしていましたが、ただの代入はそれぞれで実行するようにしようと思います。

class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
postrequisites_of_courses = [[] for _ in range(numCourses)]
indegree_of_courses = [0 for _ in range(numCourses)]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

グラフ理論の単語と問題文中の単語が混ざっており、違和感を感じました。 num_prerequisites_of_courses はいかがでしょうか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。indegree はグラフ理論の用語なんですね、1単語で言いたいことを表せるのでいいかなと思いましたが、たしかにコード全体としての一貫性に欠けていそうです。ご提案いただいた num_prerequisites_of_courses を採用させてもらおうと思います。

#

# @lc code=start
class Solution:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらに書いてある深さ優先探索版を想定していました。
https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%9D%E3%83%AD%E3%82%B8%E3%82%AB%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88
こちらのやり方で書いてみていただけますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

すみません、勘違いしていました。ちょっとリンクを参考に書き直してみます。

@thonda28
Copy link
Copy Markdown
Owner Author

thonda28 commented Apr 23, 2024

再帰関数を使った深さ優先探索でも書けますか?

コメントありがとうございます。今日少し考えて書いてみて、Step3 としてアップロードしました。所感は PR の Description に書いてみました。

@thonda28
Copy link
Copy Markdown
Owner Author

b52ec72 で再帰を使った DFS のコードを書いてみました。step1, 2 で実装した方法しかもともと知らなかったので理解に時間がかかりました。step3 のコードは Solutions を見たので、明日何も見ずに書けるまで繰り返そうと思います。

Copy link
Copy Markdown

@nodchip nodchip left a comment

Choose a reason for hiding this comment

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

よいと思います。

@thonda28
Copy link
Copy Markdown
Owner Author

Approve ありがとうございます。今日改めて何も見ずに書いてみたところ、初回はだめでしたが2回目以降はエラーなく3回連続でできました。この PR はマージします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants