题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
示例
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2] 示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
思路
最直接的方案当然就是两层for循环,这种算法复杂度为O(n*n),为了找手写算法的感觉同时摆脱IDE工具的已阿莱,还是从这个循环开始写
实现1
public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[i] + nums[j] == target) { return new int[]{i, j}; } } } return new int[0]; }
提交结果 执行用时 内存消耗 通过 56 ms 38.7 MB
朴实无华,清晰易懂,但是面试题这么做可能就直接回家了
实现2
实现1中的缺点表现在算法负责度高,而且这么高不是必须的
一次循环其实就已经把需要的值都找出来了,第二遍循环是多余的
所以接下来就是通过一遍循环找到答案,
比较直接能够想到的是循环的过程中把已经遍历过的数据存储在hash中
public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> data = new HashMap<>(nums.length); for (int i = 0; i < nums.length; i++) { int t = target - nums[i]; if (data.containsKey(t)) { return new int[]{data.get(t), i}; } else { data.put(nums[i], i); } } return new int[0]; }
提交结果 执行用时 内存消耗 通过 2 ms 38.1 MB
这种实现利用了Hash获取元素算法复杂度为O(1)
这样就可以通过一遍循环找到符合条件的元素
举一反三
这道题给我感受是,合理的利用数据结构的特点可以大大降低算法复杂度,提升处理效率
包括在实际开发中,数据结构的选用也是非常重要
例如在业务中,
输入->输出
0->0
1->1,
2->1,
3->2,
4->3,
5->5
这时就可以通过存储对应关系,也就是常说的表驱动方式实现业务
private static final int[] data = {0, 1, 1, 2, 3, 5}; public int getResult(int n) { if (n < 0 || n > data.length) { return -1; } return data[n]; }
万事开头难,加油~我对自己说
今天多学一点,明天少求人一次