Conversation
naoto-iwase
left a comment
There was a problem hiding this comment.
丁寧に検討されていて良いと思います。
全体的に読みやすいと感じました。
| ```py | ||
| class Solution: | ||
| def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]: | ||
| visited = set() |
There was a problem hiding this comment.
一応、visitedを配列で管理することもできますね。
i_to_next_j = [0] * len(nums1)len(nums1)、len(nums2)、kがいずれも大きいときには空間的に有利になるかもしれません。
| visited.add((0, 0)) | ||
| min_heap = [(nums1[0] + nums2[0], 0, 0)] |
There was a problem hiding this comment.
細かいですが、heapにpushしてからvisitedにaddする、という順序の方が自然に感じます。
| min_heap = [(nums1[0] + nums2[0], 0, 0)] | ||
| k_pairs_with_smallest_sum = [] | ||
| def add_to_heap_if_necessary(x, y): | ||
| if x < len(nums1) and y < len(nums2) and (x, y) not in visited: |
There was a problem hiding this comment.
インデックスとしてx, yはあまり一般的でないと感じるので、下に合わせてi, jとするか、丁寧にindex1, index2とする方が自然な気がします。自分ならi, jにすると思います。
| ## Step3 | ||
| ```py | ||
| class Solution: | ||
| def kSmallestPairs(self, nums1, nums2, k): |
There was a problem hiding this comment.
お疲れ様です、既に他の方の指摘のある部分以外には、特に不自然な部分は無いように感じました。
強いて指摘させていただくとしたら、nums1[0]などの参照時にindexエラーが起きないように、関数の冒頭に入力のチェックがあっても親切かもしれません(leetcodeでは想定外の入力はないですが、業務シーンを想定して)
| def kSmallestPairs(self, nums1, nums2, k): | |
| def kSmallestPairs(self, nums1, nums2, k): | |
| if k <= 0 or not nums1 or not nums2: | |
| return [] |
t9a-dev
left a comment
There was a problem hiding this comment.
すでに指摘されている点以外は特に気になる点はありませんでした。step3の改行によるコードのまとめ方が自分の好みに近いなと思いました。
| ``` | ||
| 少しだけRuntimeが改善した. | ||
|
|
||
| 別のやり方として,(i+1, j) は j == 0 のときだけpushするというやり方がある. こうすることで, (i, j)(j != 0)は(i, j-1)からの遷移に限定されるので重複を防げる. |
There was a problem hiding this comment.
このやり方自分が解いている時は思いつきませんでした。参考になります。
| def push_to_heap(x, y): | ||
| if x < len(nums1) and y < len(nums2) and (x, y) not in visited: | ||
| visited.add((x, y)) | ||
| heapq.heappush(min_heap, (nums1[x] + nums2[y], x, y)) |
There was a problem hiding this comment.
個人的には、push_to_heap という関数名だと必ず push されるように捉えてしまうため、少し関数名が長くなってしまいますがpush_to_heap_if_necessary の方が良いと感じました。
| - 新しい組を追加したときに最小のk個が維持されるようにする => heapを用いる. | ||
| - 単純な二重ループだとTLEするので, 枝刈りをしてループの回数を減らす. | ||
|
|
||
| 以上の実装を行ったがTLEは解消されなかった. |
There was a problem hiding this comment.
アルゴリズムを実装する前に、まず時間計算量を求め、その計算量から実行時間を概算することをおすすめします。
実行時間を推定する際は、計算量の式にデータの最大サイズを代入して「おおよその計算ステップ数」を算出してください。
その上で、このステップ数を「言語ごとの 1 秒あたりに処理可能なおおよその計算ステップ数」で割ると、おおよその実行時間(秒)が求まります。
一般的な PC を 1 スレッドで使用した場合の目安は次の通りです。
-
C++: 約 1~10 億ステップ/秒
CPU の周波数が数 GHz 程度であるため、IPC(Instructions per Cycle)を 1 と仮定すると、1 秒間に数十億命令を実行できます。
C++ はオーバーヘッドが小さく、1 ステップを数命令〜数十命令で実行できるため、おおよそ 1~10 億ステップ/秒が目安となります。 -
Python: 約 100 万~1000 万ステップ/秒
インタープリタ方式によるオーバーヘッドが大きく、C++ の約 100 倍遅いため、この程度が目安になります。
言語ごとの処理速度の比較として、以下の資料も参考になると思います。
解く問題
Find K Pairs With Smallest Sums
次に解く問題
Group Anagrams