数组算法题 - 两数之和
两数之和
刷题时间:
- 25/12/20

我的解法
▼java复制代码class Solution { public int[] twoSum(int[] nums, int target) { int len = nums.length; if (len < 2) return null; int[] result = new int[2]; for (int i = 0; i < len - 1; i++) { for (int j = i + 1; j < len; j++) { if (nums[i] + nums[j] == target) { result[0] = i; result[1] = j; break; //这里仅仅跳出了内存循环, 如果要跳出外层循环,应该设置标记 } } } return result; } }
优点:
- 边界处理正确(len < 2)
- 使用了j = i + 1避免重复配对
缺点:
- O(n^2)的时间复杂度过高, 可能会超时
- 没有充分利用题目信息:"保证存在解", 可以不判断边界
- bug: 找到答案后break只跳出了内层循环, 跳出外层循环需要设置标记
优化:
▼java复制代码class Solution { public int[] twoSum(int[] nums, int target) { // 更简洁的边界判断 if(nums == null || nums.length < 2) return new int[0]; //返回空数组而不是null for (int i = 0; i < nums.length - 1; 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]; //题目保证有解, 不执行 } }
题解
▼java复制代码class Solution { public int[] twoSum(int[] nums, int target) { // key = 数值, value = 下标 Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int gt = target - nums[i]; // 检查补数是否出现过 if (map.containsKey(gt)) { return new int[] { map.get(gt), i }; } // 将当前数值与下标存入哈希表, 这行代码需要放在后面, 防止自己配对自己 map.put(nums[i], i); } return new int[0]; } }
-
思路:
- 暴力解法的时间复杂度是O(n^2), 空间复杂度是O(1)
- 如何优化,要么减少时间复杂度,要么减少空间复杂度, 在程序运行中,往往时间复杂度的优化要优先于空间复杂度
- 那么就优化时间复杂度到O(n).
- 两层for循环,减少到一层for循环即可
- 那么"找两个数的和等于target"可以转变为: "对于
nums[i], 查找target - nums[i]是否出现过" - 可以采用哈希表, 使用哈希表来存储出现过的
nums[i],key存储nums[i],value存储i(索引) - 在内循环中,判断map中是否存在key =
target - nums[i], 如果存在,则输出结果(两个索引)- 如果不存在, 则将
nums[i]存入map, 等待被匹配
- 如果不存在, 则将
- 那么"找两个数的和等于target"可以转变为: "对于
- 哈希表法的时间复杂度是O(n), 空间复杂度是O(n).
- 这就是用空间换时间
- 暴力解法的时间复杂度是O(n^2), 空间复杂度是O(1)
-
算法思想
- 用空间换时间 - 哈希表
- 为什么要这样设计哈希表:
key = 数值, value = 下标- map.containsKey()可以判断是否存在键, 而题目需要判断的就是是否存在
target - nums[i]. - 题目需要返回的是索引, 那么value就可以通过key获取索引
- map.containsKey()可以判断是否存在键, 而题目需要判断的就是是否存在
- 为什么不能"先全加入map, 再查找"?
- 可能导致自己匹配自己的情况: (如
[3],target=6). - 所以要边查边存
- 可能导致自己匹配自己的情况: (如
- 边界条件
- 在我的解法中,
if (len < 2) return null;题目保证有解, 这是可以不判断的 - 但是这样的编程习惯是好的!
- 在我的解法中,
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
作者分享
Day 7
✅ 今天做了:云图库项目的 5-用户传图
1.通过URL传图 2.批量抓取和上传图片
⏰ 明天计划:最少把6-图片优化给做完!
📚 今日感悟:
做项目,真的耗时间,并不是将代码简单复制粘贴那么简单,还需要理解代码,运行跑起来调试,这些花的时间才是主要的!
3
字符串算法题 - 字符串相加
3
Day 6
✅ 今天做了:一道算法题(买卖股票的最佳时机), 一道八股(面向对象的三大特征)
『 数组算法 - 买卖股票的最佳时机 』💎 https://www.codefather.cn/post/2004184783197937665
⏰ 明天计划:一道算法,一道八股,项目
📚 今日感悟:算法还是先用暴力解法, 后面看题解是运用了贪心思想的一次遍历.
面向对象的三大特征, 封装是基础, 继承实现了代码的复用和扩展, 多态通过方法重载和方法重写实现了"同一接口,多种实现"的功能
4
数组算法 - 买卖股票的最佳时机
4
Day 5
✅ 今天做了:写了两道八股题, 健身练了肩
⏰ 明天计划:项目, 两道算法, 一道八股
📚 今日感悟:效率好低啊, 早上学了, 下午健身,晚上有事. 效率真的太低了, 也就非健身日学习时间能长一点.
4
