背景
感兴趣的小伙伴可以在leetcode中找到这个题:leetcode.cn/problems/tw…
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
首先题目给出一个数组和一个目标值,该数组里面的数字不会出现重复,我们的目标就是通过以下函数判断数组中哪两个位置的数字之和等于目标值,转换成公式如下:
nums[x] + nums[y] = target 复制代码
求出x和y的值。
分析
根据题目给出的条件:数组中不会出现重复的数字;那么我们就可以先把这个数组转换成一个键值对。
例如我们的数组是[2,7,11,15],那么我们需要转成{2:0,7:1,11:2,15:3}这样的键值对:
假如我们目前的target是9的话,那么第二步需要先用target减掉第一个数字2,拿到结果7,我们再通过结果7作为key去键值对里面查询是否存在这个key,如果存在,那么就找到了结果,如果不存在,那么我们需要依次使用target减掉第二个数字7,再用得到的结果作为key查找;依次循环上面的步骤,直至到最后。
java实现
public int[] twoSum(int[] nums, int target) { // 创建map Map<Integer, Integer> map = new HashMap<>(); for (int i = nums.length - 1; i >= 0; i--) { // 依次取出每一个数字 int num = nums[i]; // 计算key int key = target - num; // 检查是否存在map中 if (map.containsKey(key)) { // 如果存在,给出对应的索引值 return new int[]{i, map.get(key)}; } // 存储到map中 map.put(num, i); } // 如果没有找到,返回null return null; } 复制代码
python实现
def twoSum(self, nums: List[int], target: int) -> List[int]: # 创建键值对 map = {} # 遍历数组 for i in range(len(nums)): # 依次取数字 num = nums[i] # 计算key key = target-num # 判断key是否在键值对中 if key in map: # 如果找到了,就返回结果 return [i,map[key]] # 把num和索引值放进键值对中 map[num] = i # 如果都找不到,那么返回nil return nil 复制代码
【注意】python的语法一定要多注意每行前面的空格,保证不要出现不合适的空格导致语法有问题。
map={}
也可以使用map=dict()
来表示,这样会更明确一点。
rust实现
use std::collections::HashMap; pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> { // 创建map键值对 let mut map: HashMap<i32, i32> = HashMap::new(); // 遍历数组 for (i, v) in nums.iter().enumerate() { // 计算key值 let key = target - v; // 检查key是否在键值对中 if map.contains_key(&key) { // 如果在键值对中,就返回对应的索引值 let index = map.get(&key).unwrap(); // 因为i的类型是usize类型,所以这里需要转换成i32类型 // index拿到的结果是引用,所以需要通过`*index`拿到具体的值 return vec![i as i32, *index]; } // 插入键值对 map.insert(*v, i as i32); } // 如果都没有匹配到,那么返回空数组 vec![] } 复制代码
上面我们使用三种语言实现了两数之和
的算法题解,感兴趣的小伙伴可以根据这个算法使用你们自己擅长的语言来实现,有不同见解的小伙伴也欢迎给出更好的算法题解。