#はじめに
こんばんは.
M1就活生がLeetCodeから,easy問題を中心にPythonを用いて解いていきます.
↓では,解いた問題のまとめを随時更新しています.
まとめ記事
#問題
今回解いたのは,難易度easyから 問題26のRemove Duplicates from Sorted Array です.
問題としては,ソートされたリストnums
から,重複した要素を削除し,最終的なリストnums
の個数を返すというもの.このときnums
は直接返さずに重複した要素を削除して元のリストから変更します.
入力例と出力例は以下の通りです.
Example 1:
Input: nums = [1,1,2]
Output: 2, nums = [1,2,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
Example 2:
Input: nums = [0,0,1,1,1,2,2,3,3,4]
Output: 5, nums = [0,1,2,3,4,_,_,_,_,_]
Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3, and 4 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
#書いたコード
今回の問題は,リストnums
の重複要素をなくすため,set
を使い,それをまたlist
を使ってリスト型に戻しています.このとき,set
を使うと元の順序を保持してくれないため,sorted
でリストの中身を整列させました.
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
nums[:] = sorted(list(set(nums)))
return len(nums)
ここで詰まった...
今回の問題では,元のリストを変更するためにnums = ...
ではなく,nums[:] = ...
とスライスを用いています.
Pythonでは,関数にリストを引数として取ると値渡しではなく,参照渡しとなります(変数などは値渡し).これは,id
で確認することができます.そのため,今回のような問題では,関数内でリストを変更すれば,そのリストを返さずとも,リストの中身が書き換えられることとなります.
しかし,次のようなコードではどうでしょうか.同じリストでも,別々のidとなっています.このように,同じリストでも,別々のidとなるのは,list()
やsorted()
が,新しいlistオブジェクトを生成するためです(元のリストをソートするsort()
などもあります).
def tmp(l):
print(id(l)) # 4551362632 ... (1)
l = list(set(l))
print(id(l)) # 4551378696 ... (2)
l = sorted(l)
print(id(l)) # 4551378376 ... (3)
l.sort()
print(id(l)) # 4551378376 ... (3)
nums = [1, 2, 3]
print(id(nums)) # 4551362632 ... (1)
tmp(nums)
print(id(nums)) # 4551362632 ... (1)
元のリストの中身を書き換える場合は,スライスを用います.
def tmp(l):
print(id(l)) # 4564949064 ... (1)
l[:] = list(set(l))
print(id(l)) # 4564949064 ... (1)
l[:] = sorted(l)
print(id(l)) # 4564949064 ... (1)
l[:].sort()
print(id(l)) # 4564949064 ... (1)
nums = [1, 2, 3]
print(id(nums)) # 4564949064 ... (1)
tmp(nums)
print(id(nums)) # 4564949064 ... (1)
このように,スライスを用いると,新しいlistオブジェクトを生成する場合でも元のリストの中身を書き換えることが可能になります.
#おわりに
今回の問題は一見簡単そうに見えましたが,実際に解いてみるとなかなかハマってしまう事態になりました.調べながらアウトプットすることで,より知識として身についた気がします.
今回書いたコードはGitHubにもあげておきます.