算法小白刷力扣 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) 的肯定不算最优解,是暴力破解,来看看我的暴力破解。

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 不就行了,我哭~
这里贴一下官方提供的暴力破解法以供参考:

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. 正确解法

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

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 对应的统计值。

相关推荐

  1. 算法 1 - 之和

    2024-04-24 17:44:03       13 阅读
  2. 【暴1. 之和

    2024-04-24 17:44:03       16 阅读
  3. 题笔记(1之和(C++)

    2024-04-24 17:44:03       12 阅读
  4. 1.之和

    2024-04-24 17:44:03       12 阅读
  5. 1.之和

    2024-04-24 17:44:03       8 阅读
  6. 100】1.之和__231206

    2024-04-24 17:44:03       45 阅读
  7. 面试150题 |1. 之和

    2024-04-24 17:44:03       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-24 17:44:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-24 17:44:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-24 17:44:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-24 17:44:03       18 阅读

热门阅读

  1. linux-mysql安装

    2024-04-24 17:44:03       11 阅读
  2. vue实现进入某个页面后替换地址栏路径

    2024-04-24 17:44:03       14 阅读
  3. 微信小程序实现蓝牙连接通讯

    2024-04-24 17:44:03       10 阅读
  4. Vue 3 Hooks:优雅管理组件状态的完整指南

    2024-04-24 17:44:03       10 阅读
  5. Tomcat服务器的优化经验

    2024-04-24 17:44:03       12 阅读
  6. 前端vue scope的定义以及用法

    2024-04-24 17:44:03       12 阅读
  7. 鼠标悬停的几种方式

    2024-04-24 17:44:03       10 阅读
  8. Python常用模块

    2024-04-24 17:44:03       7 阅读
  9. 探索电子元器件商城:从原型到批量生产的选择

    2024-04-24 17:44:03       12 阅读