1. 2 つの数値の合計
質問の説明
整数配列nums
と整数ターゲット値が与えられた場合、target
配列内で合計がターゲット値となる2 つのtarget
整数を見つけて、それらの配列の添字を返してください。
問題の分析と実装
難易度:【簡単】
データ構造:配列
基本的な実装方法:
- ブルートフォース列挙
- ダブルポインタ方式
- ハッシュテーブル方式など
実装 1: 暴力的な列挙
- 配列内の各数値を列挙し
x
、その数値が配列内に存在するかどうかを確認します。target - x
x
各要素を 2 回使用することはできないため、次の要素のみを検索する必要があります。target - x
# Use Python to solve
def two_sum(nums: List[int], target:int) -> List[int]:
'''
使用暴力枚举法求两数之和
参数:
nums (list[int]): 包含整数的列表
target(int): 目标和
返回值:
list[int]: 包含两个索引的列表,这两个索引对应的元素之和等于目标和target如果没有找到符合条件的索引对,返回空列表[]
'''
arr_length = len(nums)
if not nums or arr_length < 2:
return []
# 使用暴力枚举法来一一确认符合条件的元素索引
for i in range(arr_length):
for j in range(i + 1, arr_length):
if nums[i] = target - nums[j]
return [i, j]
return []
時間計算量の分析:
- 最良のケース: 最初の走査で修飾されたインデックス ペアが見つかった場合、時間計算量はO ( 1 ) O (1)になります。○ (1)
- 最悪のシナリオ: 一致するインデックス ペアが見つからない場合、2 レベルのループを完全に通過する必要があり、時間計算量はO ( n 2 ) O(n^2)になります。O ( n2 )、ここで n は
nums
リストの長さ - 平均的なケース: 平均して、2 レベルのループを通過する必要があり、時間計算量はO ( n 2 ) O(n^2)です。O ( n2 )
空間の複雑さの分析:
- 追加のスペースは使用されず、データの格納には定数レベルの変数のみが使用されるため、スペースの複雑さ: O ( 1 ) O (1)○ (1)
実装 2: ダブルポインタ方式
- 配列の値とインデックスをタプルとして保存するリスト (List) を作成し、それらを (値で) 並べ替えます
- 左右のポインタを定義し、左ポインタが右ポインタより小さい場合にループ判定を行います。
- 左右のポインター値の合計がターゲット値と等しい場合、そのインデックスを新しいリスト (num_list) に追加します
# Use Python to solve
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
'''
使用双指针方法解决两数之和
参数:
nums (list[int]): 整数数组
target(int): 目标值
返回值:
nums_list(list[int]): 和为目标值的两个整数的数组下标
'''
arr_length = len(nums)
if not nums or arr_length < 2:
return []
# 存放最终结果
num_list = []
# 创建一个列表按(num, index)格式存放
nums_with_index = [(num, index) for index, num in enumerate(nums)]
# 对nums_with_index按照数字大小进行排序
nums_with_index.sort()
# 定义左右两个指针
left, right = 0, arr_length - 1
# 当左指针小于右指针时,进行循环
while left < right:
# 如果左指针和右指针所指数字的和等于目标值
if nums_with_index[left][0] + nums_with_index[right][0] == target:
num_list.append(nums_with_index[left][1])
num_list.append(nums_with_index[right][1])
break
# 如果左指针和右指针所指数字的和小于目标值
elif nums_with_index[left][0] + nums_with_index[right][0] < target:
# 左指针右移
left += 1
else:
# 右指针左移
right -= 1
return num_list
時間計算量の分析:
- 最良のシナリオ: 最初のループで一致する数値ペアが見つかった場合、時間計算量はO ( 1 ) O(1)になります。○ (1)
- 最悪のシナリオ: 一致する数値ペアが見つからない場合、リスト全体を走査する必要があり、時間計算量はO ( n ) O(n)になります。O ( n )、ここで n は
nums_with_index
の長さ - 平均的なケース: 平均すると、リスト全体を走査する必要があり、時間計算量はO ( n ) O(n)です。O ( n )
空間の複雑さの分析:
- 余分な空間が作成される
nums_with_index
ため、空間の複雑さはO ( n ) O(n)になります。O ( n )
実装 3: ハッシュ テーブル
- 配列のハッシュテーブルを作成する
- それぞれについて
x
、まずハッシュ テーブルに存在するかどうかをクエリしtarget - x
、次にx
ハッシュ テーブルに挿入して、それx
自体が一致しないことを確認します。
# Use Python to solve
def two_sum(nums: List[int], target: int) -> List[int]:
'''
使用哈希表方法解决两数之和问题
参数:
nums (list[int]): 包含整数的列表
target (int): 目标和值
返回值:
List[int]: 包含两个索引的列表,这两个索引对应的元素之和等于目标和target如果没有找到符合条件的索引对,返回空列表[]
'''
arr_length = len(nums)
if not nums or arr_length < 2:
return []
nums_map = {
} # 创建一个空的哈希表,用于存储数字和索引的映射关系
for i, num in enumerate(nums): # 遍历列表,同时获取数字的索引
if target - num in nums_map: # 如果target - num在哈希表中存在,说明之前出现过一个数字与当前num之和等于target
return [nums_map[target - num], i] # 返回之前记录的索引和当前索引
nums_map[num] = i # 将当前数字和索引添加到哈希表中
return [] # 如果没有找到符合条件的索引对,返回空列表[]
時間計算量の分析:
- 最良のシナリオ: リストを走査するときに最初の要素で一致する数値ペアが見つかった場合、時間計算量はO ( 1 ) O(1)になります。○ (1)
- 最悪のシナリオ: 一致する数値ペアが見つからない場合、リスト全体を完全に走査する必要があり、時間計算量はO ( n ) O(n)になります。O ( n )、ここで n は
nums
の長さ - 平均的なケース: 平均すると、リスト全体を走査する必要があり、時間計算量はO ( n ) O(n)です。O ( n )
空間の複雑さの分析:
- O ( n ) O( n )O ( n )