配列内の重複する数値を見つけます。
長さがnの配列numのすべての数値は、0からn-1の範囲です。配列内のいくつかの数値が繰り返されていますが、何回繰り返されているのか、また各数値が何回繰り返されているのかわかりません。配列内で重複する番号を見つけてください。
例1:
入力:
[ 2、3、1、0、2、5、3 ]
出力:2または3
制限:
2 <= n <= 100000
ソース:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/shu-zu-zhong-zhong-zhong-fu-de-shu-zi-lcof
著作権は控除ネットワークに属しています。商用転載の正式な許可書に連絡し、非商用転載の出典を明記してください。
解決策:
アイデア1:配列
繰り返される数を見つけるだけでよく、配列を使用してシミュレートでき、添え字を使用して数に対応できます。配列内の値が発生数として使用されます。
時間と空間の両方の複雑度はO(n)
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
length = len(nums)
count = [0] * length
for i in range(length):
count[nums[i]] += 1
if count[nums[i]] > 1:
return nums[i]
return -1
アイデア2:辞書
上記の配列を辞書に置き換えるだけで、回数をカウントできます。
時間の複雑さ:O(n)
スペースの複雑さ:O(n)、上記の配列より小さくする必要があります。
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
length = len(nums)
count = {}
for i in range(length):
if nums[i] in count:
return nums[i]
else:
count[nums[i]] = 1
return -1
アイデア3:コレクションを設定する
上記の配列をセットのコレクションに置き換え、コレクションにすでに存在するかどうかを確認します。
時間の複雑さ:O(n)
スペースの複雑さ:O(n)
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
length = len(nums)
count = set()
for i in range(length):
if nums[i] in count:
return nums[i]
else:
count.add(nums[i])
return -1
アイデア4:インプレース置換アルゴリズム
この方法は、トピックに基づいて非常に賢いです:サイズNの配列の値は[0、n-1]にあり、配列が繰り返されない場合、以下の表の数値に対応できるはずです対応するものは、下付き文字i = num [i]です。したがって、この点を使用して判断することができます。特定の添え字が2つの値に対応している場合は、重複した数値が存在します。
処理方法:配列を走査して順序を調整し、iとnums [i]を一致させます。i!= Nums [i]が等しくない場合は、nums [i]を添え字nums [i]に入れる必要があります。位置を決め、インデックスnums [i]の値をインデックスiの位置に置き換えます。この時点でiがnums [i]と等しくない場合は、上記の操作を続行します。
次に例を示します。
下表:0 1 2 3
値:1 3 0 2
上記の計算方法で手動で把握できます。
この質問の独創的な点は、追加のストレージスペースが不要であり、時間は上記と基本的に同じであり、特定の環境でのソート方法が提供されることです。
時間の複雑さ:O(n)
スペースの複雑さ:O(1)
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
length = len(nums)
# 原地交换
for i in range(length):
while i != nums[i]: # 说明num[i]应该放到下标为num[i]的位置
if nums[nums[i]] == nums[i]: # 该位置已经匹配好了,则说明存在重复
return nums[i]
t = nums[nums[i]]
nums[nums[i]] = nums[i]
nums[i] = t
return -1