Leetcode刷题日记|算法 第一题 twoSum(Java版)

题目内容

写一个叫twoSum的方法,传入一个整数数组nums和一个整数target,要求返回两个数字的下标,使这两个下标所对应的数相加为target。
注意
1.不会出现某个输入无解的情况(边际情况忽略)
2.元素不能重复使用
3.答案返回顺序随意

测试程序样例

class Solution {
    public int[] twoSum(int[] nums, int target) {
        //在这里完成我们的代码
    }
}

示例

输入:nums = [2, 7, 11, 15], target = 9
输出:[0, 1]
解释:nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]

解题思路

在面对这个问题时,我首先考虑了一种简单的解决方法,即使用两层循环来遍历数组,寻找满足条件的数对,在满足条件时立即返回结果,不满足则继续遍历。以下是我的初始解答:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2]; // 声明并初始化结果数组

        for (int i = 0; i < nums.length; ++i) {
            for (int j = i + 1; j < nums.length; ++j) { // 注意这里从 i+1 开始,避免重复计算
                if (target == nums[i] + nums[j]) {
                    result[0] = i;
                    result[1] = j;
                    return result; // 找到目标,返回结果
                }
            }
        }
        
        return result; // 如果没有找到目标,返回初始值[0, 0]
    }
}

这种时间复杂度为O(n^2)的简单粗暴的算法顺利帮我通过了测试,测试结果如下
耗时:45毫秒 击败45.5%的Java用户
占用空间:43.7MB 击败70.19%的Java用户
虽然在空间占用上表现不错,但是这个时间让我这个学习时长两年半的大学牲感到差强人意,我对这道题进行了进一步的思考:

  1. 这个解法的时间复杂度很高,尤其是对于大规模数据。我是否可以通过更有效的方法来解决这个问题?
  2. 我的解答没有考虑空间复杂度,它创建了一个新的数组来存储结果。是否有更节省内存的方式?

同时,LeetCode上还有一个追问在若有若无的提醒我:能否在不使用双重循环的情况下解出这道题?

我们顺着这个问题继续思考,如果不使用双重循环,那就要在使用一个循环的情况下完成数组之间的匹配,考虑到Java语言的特性,我选择了Hash Table来提高效率,利用哈希表存储数组元素和它们的索引的映射关系,种方法具有更低的时间复杂度(O(n)),因为哈希表的查找操作通常是O(1)。同时,它减少了额外的内存消耗。

方法优化

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 使用 HashMap 存储已经遍历过的数字及其索引
        Map<Integer, Integer> selections = new HashMap<>();

        for (int i = 0; i < nums.length; ++i) {
            int complement = target - nums[i];
            // 检查是否已经存在与当前数字相加等于目标值的数字
            if (selections.containsKey(complement)) {
                // 如果找到满足条件的数字,返回它们的索引
                return new int[]{i, selections.get(complement)};
            }
            // 将当前数字及其索引添加到 HashMap 中
            selections.put(nums[i], i);
        }
        
        // 如果没有找到满足条件的数字对,抛出异常
        throw new IllegalArgumentException("No valid solution found!");
    }
}

附上运行结果:
耗时:2毫秒 击败81.32%的Java用户
占用空间:43.9MB 击败37.52%的Java用户
抛开占用空间变高不谈,单看2毫秒的耗时还是可以说进步明显的

最后希望这篇文章可以帮到大家!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值