two sum(LeetCode)
该题目是leetcode上一道非常简单但是经典的题,现把该题的较为经典的解题思路进行总结
1 题目描述
该题的输入是给定一个数组,以及一个目标值,通过计算找出数组中两个元素和等于目标值的各自的索引。
如下例子所示:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
2 python解题思路
1 class Solution(object): 2 def twoSum(self, nums, target): 3 if len(nums) <= 1: 4 return False 5 buff_dict = {} #创建一个空字典 6 for i in range(len(nums)): #循环查找nums数组中的每一个元素 7 if nums[i] in buff_dict: #判断该元素是否在字典中,如果在字典中,进入该分支 8 return [buff_dict[nums[i]], i] #将该键(nums[i])在字典中的值以及该值在nums数组中的索引返回作为最终结果 9 else: 10 buff_dict[target - nums[i]] = i #如果数组中该索引的值不在字典中,那么将该目标值(也就是输入的和targrt)减去该值作为字典中的一个键,把该值的索引作为键对应的值存储
这种解题思路的巧妙之处就在于一次循环就可以完成搜索,时间复杂度是O(n)
原因是首先通过索引循环数组中的每个值,假如该值不在字典中,那么存储的是目标值与该值的差,以及该值在数组中索引,在之后的搜索中是判断数组中每个值是否在字典中,额就是是否正好等于这个差,如果等于,那么说明这两个数的和正好就是目标值,如果字典中不存在该值,那么同样将该值和目标值的插值存于数组中,就是是更新了字典。
每次的循环判断都是去查找数组中之前的所有元素与目标值的差,这是该解题方式的巧妙之处。
该题用到了python中的字典,也就是Java或者C++中的hash表,在python中的基本使用如下所示:
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
1 d = {key1 : value1, key2 : value2 }
3 java解题思路
将python的解题思路用Java实现如下所示:
1 class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 Map<Integer, Integer> map = new HashMap<>(); 4 for (int i = 0; i < nums.length; i++) { 5 int complement = target - nums[i]; 6 //map.put(complement, i); 7 if (map.containsKey(nums[i])) { 8 return new int[] { map.get(nums[i]), i}; 9 } 10 else { 11 map.put(complement, i); 12 } 13 } 14 throw new IllegalArgumentException("No two sum solution"); 15 } 16 }