算法小白刷力扣 1 - 两数之和

题目描述

原题链接:https://leetcode.cn/problems/two-sum/description/

给定一个整数数组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]

提示

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

2. 我的解法

毫无疑问,算法小白首先想到的肯定是暴力破解。什么是暴力破解?众所周知,凡是用了双层循环导致算法复杂度为 O(n^2) 的肯定不算最优解,是暴力破解,来看看我的暴力破解。

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];
        for(int i = 0; i < nums.length; i++) {
            boolean found = false;
            // 这里是关键,由于是从前往后挨个找,那第 i 个元素之前的元素已经找过了,就不需要再算了,因此每次从第 i + 1 个元素开始找
            for(int j = i + 1; j < nums.length; j++) {
                if(nums[i] + nums[j] == target) {
                    result[0] = i;
                    result[1] = j;
                    found = true;
                    break;
                }
            }
            if(found) {
                break;
            }
        }
        return result;
    }
}

因为题目明确说明只有一个有效答案,所以找到第一组解时就应该停止循环,所以用了一个 flag 标志,如果找到就 break,但看了官方解法,这一步纯属多余,找到直接 return 不就行了,我哭~

这里贴一下官方提供的暴力破解法以供参考:

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

3. 正确解法

照例先贴代码,因为我没想到,所以没思路可说:

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; ++i) {
            if (hashtable.containsKey(target - nums[i])) {
                return new int[]{hashtable.get(target - nums[i]), i};
            }
            hashtable.put(nums[i], i);
        }
        return new int[0];
    }
}

只有一层循环,显然时间复杂度降为了 O(n)。但没想到的是它竟然用了哈希表!我以为不能直接用现成的数据结构呢,还寻思有啥特殊技能,原来是用了大杀器,那不还是用空间换时间的套路嘛,害,所以所谓更优来来回回也就这点儿事儿,理解了这一点,思路就打开了。

那他是怎么用一层循环加哈希表就搞定的呢?重点就是用了哈希表,给遍历过程赋予了记忆的能力,即已经遍历过哪些元素会在哈希表中单独存一份以备后续使用,且哈希表的查找复杂度为 O(1),很容易就能判断一个元素是否存在,有了这两个能力,就很简单了。每次遍历到元素num[i]时,target - num[i] 就是我们要找的元素,所以我们只要判断在哈希表中有没有 target - num[i] 就可以了。

但记忆能力还不是用哈希表的唯一原因,如果我们只需要将遍历过的元素记下来并判断是否需要,那用 HashSet 就可以了,但很显然,HashSet 只能存单个元素,不能存键值对,当我们想获取目标元素的索引时就不行了,所以将目标元素的索引存为哈希节点的 value 中就能轻易拿到了。

谈到哈希表,其查找能力在算法题解中用到的最多,此外还可借助映射特性汇总一组数据中每个 Key 对应的统计值。

相关推荐
呆呆的猫9 分钟前
【LeetCode】227、基本计算器 II
算法·leetcode·职场和发展
Tisfy11 分钟前
LeetCode 1705.吃苹果的最大数目:贪心(优先队列) - 清晰题解
算法·leetcode·优先队列·贪心·
余额不足1213831 分钟前
C语言基础十六:枚举、c语言中文件的读写操作
linux·c语言·算法
测试老哥35 分钟前
外包干了两年,技术退步明显。。。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
yuanManGan2 小时前
数据结构漫游记:静态链表的实现(CPP)
数据结构·链表
火星机器人life3 小时前
基于ceres优化的3d激光雷达开源算法
算法·3d
虽千万人 吾往矣3 小时前
golang LeetCode 热题 100(动态规划)-更新中
算法·leetcode·动态规划
arnold664 小时前
华为OD E卷(100分)34-转盘寿司
算法·华为od
ZZTC4 小时前
Floyd算法及其扩展应用
算法
测试19984 小时前
外包干了2年,技术退步明显....
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展