算法练习(Java)

题目一

给定一个整数数组 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如何取舍

  1. 查找效率

    • HashMap 提供了平均情况下接近 O(1) 的时间复杂度来检索元素,这意味着即使数据量很大,查找速度也很快。
    • 多层for循环的时间复杂度通常是 O(n^k),其中 n 是数组的长度,k 是循环的层数。随着数据量的增加,所需时间会急剧增加。
  2. 内存占用

    • HashMap 可能会占用较多的内存,因为它需要存储键和值,以及维护哈希表的结构。
    • for循环通常只占用固定的内存空间,但当处理的数据量非常大时,循环本身并不会增加额外的内存负担。
  3. 代码可读性

    • 使用 HashMap 可能会使代码更简洁,更容易理解,特别是当涉及到复杂的查找逻辑时。
    • for循环可能在某些情况下更直观,尤其是处理简单的数据结构时。
  4. 初始化成本

    • HashMap 在使用前需要初始化,并且当数据量变化时可能需要重新计算哈希值和调整大小,这会带来额外的开销。
    • for循环没有初始化成本,但循环次数多时,执行时间可能会很长。
  5. 线程安全

    • HashMap 默认不是线程安全的,如果需要在多线程环境中使用,可能需要使用 ConcurrentHashMap 或其他同步机制。
    • for循环在单线程环境中是线程安全的,但在多线程环境中需要额外的同步措施。
  6. 资源占用

    • 循环结构本身不会占用太多资源,但循环次数多时会占用CPU时间。
    • HashMap 集合对象会占用内存资源,如果数据量大,可能会成为内存占用的瓶颈。

在决定使用哪种方法时,应该考虑以下问题:

  • 数据量有多大?
  • 查找操作的频率如何?
  • 是否需要频繁修改数据结构?
  • 性能和内存使用哪个更重要?

通常,如果数据量不大,或者查找操作不频繁,for循环可能是一个简单有效的选择。但如果数据量很大,或者需要频繁进行查找操作,使用 HashMap 可能会更高效。

个人理解:可以类比我们日常在京东和淘宝购物平台,map指京东,for指的淘宝,京东拥有自己的仓库,仓库成本高,配送时间快用户体验好,淘宝配送时间相对长,但是没有仓库的管理成本。

在实际应用中,可以通过性能测试来评估不同方法的资源占用和执行效率,从而做出更合适的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值