题目一
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int[] twoSum(int[] nums, int target) {
// 创建一个HashMap来存储数组元素的值和它们的索引
Map<Integer, Integer> map = new HashMap<>();
// 遍历数组
for (int i = 0; i < nums.length; i++) {
// 计算与当前元素相加等于target的另一个元素的值
int complement = target - nums[i];
// 检查这个元素是否已经在map中
if (map.containsKey(complement)) {
// 如果存在,返回它们的索引
return new int[] {map.get(complement), i};
}
// 将当前元素的值和索引存入map中
map.put(nums[i], i);
}
// 如果没有找到答案,返回空数组(根据题目描述,这种情况不会发生)
return new int[] {};
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {2, 7, 11, 15};
int target = 9;
int[] result = solution.twoSum(nums, target);
System.out.println("下标: " + result[0] + ", 下标: " + result[1]);
}
}
代码总结
在Java中,解决这个问题的一种有效方法是使用哈希表(HashMap)。
这段代码定义了一个名为 twoSum
的方法,它接受一个整数数组 nums
和一个整数 target
作为参数。方法使用一个 HashMap
来存储遍历过程中每个元素的值和它的索引。对于数组中的每个元素,它计算出与当前元素相加等于 target
的另一个元素的值(称为 complement
)。如果 complement
已经在 map
中存在,说明找到了一对和为 target
的元素,方法随即返回这两个元素的索引。如果遍历完数组都没有找到这样的一对元素,根据题目描述,这种情况不会发生,因此方法返回一个空数组。
扩展
当看到题目时,我个人是习惯性思维是使用双层for循环遍历它,并对target值做比对,找到对应的两个nums并返回下标。既然都聊到到这里了我们不妨思考下,在找符合特定要求的数据时,我们使用HashMap集合结构的特性(key和values键值对),还是使用多层for循环,for循环体它占内存否?它遍历趟数所损耗系统时间如何?相对使用map的内存开销,我们应该如何取舍。
多层for和Map如何取舍
-
查找效率:
HashMap
提供了平均情况下接近 O(1) 的时间复杂度来检索元素,这意味着即使数据量很大,查找速度也很快。- 多层for循环的时间复杂度通常是 O(n^k),其中 n 是数组的长度,k 是循环的层数。随着数据量的增加,所需时间会急剧增加。
-
内存占用:
HashMap
可能会占用较多的内存,因为它需要存储键和值,以及维护哈希表的结构。- for循环通常只占用固定的内存空间,但当处理的数据量非常大时,循环本身并不会增加额外的内存负担。
-
代码可读性:
- 使用
HashMap
可能会使代码更简洁,更容易理解,特别是当涉及到复杂的查找逻辑时。 - for循环可能在某些情况下更直观,尤其是处理简单的数据结构时。
- 使用
-
初始化成本:
HashMap
在使用前需要初始化,并且当数据量变化时可能需要重新计算哈希值和调整大小,这会带来额外的开销。- for循环没有初始化成本,但循环次数多时,执行时间可能会很长。
-
线程安全:
HashMap
默认不是线程安全的,如果需要在多线程环境中使用,可能需要使用ConcurrentHashMap
或其他同步机制。- for循环在单线程环境中是线程安全的,但在多线程环境中需要额外的同步措施。
-
资源占用:
- 循环结构本身不会占用太多资源,但循环次数多时会占用CPU时间。
HashMap
集合对象会占用内存资源,如果数据量大,可能会成为内存占用的瓶颈。
在决定使用哪种方法时,应该考虑以下问题:
- 数据量有多大?
- 查找操作的频率如何?
- 是否需要频繁修改数据结构?
- 性能和内存使用哪个更重要?
通常,如果数据量不大,或者查找操作不频繁,for循环可能是一个简单有效的选择。但如果数据量很大,或者需要频繁进行查找操作,使用 HashMap
可能会更高效。
个人理解:可以类比我们日常在京东和淘宝购物平台,map指京东,for指的淘宝,京东拥有自己的仓库,仓库成本高,配送时间快用户体验好,淘宝配送时间相对长,但是没有仓库的管理成本。
在实际应用中,可以通过性能测试来评估不同方法的资源占用和执行效率,从而做出更合适的选择。