【LeetCode】1.两数之和(简单)

【被OJ毒打的第一天】LeetCode_简单_1.两数之和

点此去做

题干:
    给定一个整数数组 nums 和一个整数 target,请你在该数组中找出和为 target 的那两个整数,并用一个
    二维整数数组的形式返回他们的数组下标
提示:
    假设每种输入只对应一个答案
    不能重复使用这个数组中同样的元素
输入:
    nums = [1,2,7,3]
    target = 9
输出:
    [1,2]

1.普通做法

执行用时:256ms,9.3MB

作为一个懒人,首先用最不需要思考的办法过了再说......

思想:两层循环,遍历所有求和情况,理论上时间复杂度是 O(n^2)

vector<int> twoSum(vector<int>& nums, int target) {
    vector<int> res;
    for (int i = 0; i < nums.size(); i++) {
        for (int j = i + 1; j < nums.size(); j++) {
            if (nums[i] + nums[j] == target) {
                res.push_back(i);
                res.push_back(j);
                break;
            }
        }
    }
    return res;
}

2.进阶做法

执行用时:16ms,10.2MB

执行时间恰好是刚才那个方法的平方根,说明此方法时间复杂度应为 O(n)

思想:鉴于哈希容器的查找 map.find() 时间复杂度为 O(1),用空间换时间

实现:遍历一次 nums,将 (nums[i], i) 的键值对存入一个 map;遍历过程中,如果在 map 中找到 target - nums[i] ,就说明当前值和之前的某个值和为 target,故可以将当前的 i 和 map[target - nums[i]] 的值作为结果返回

vector<int> twoSum(vector<int>& nums, int target) {
    vector<int> res;
    map<int, int> pairs;
    for (int i = 0; i < nums.size(); i++) {
        int x = target - nums[i];
        if (pairs.find(x) != pairs.end()) {
            res.push_back(pairs[x]);
            res.push_back(i);
            return res;
        }
        pairs[nums[i]] = i;
    }
    return res;
}

3.神仙做法

执行用时:12ms,10MB(多执行几次发现其实也并不是每次都这么快)

思想:在方法2的基础上,使用效率更高的 unordered_map

vector<int> twoSum(vector<int>& nums, int target) {
    vector<int> ret;
    unordered_map<int, int> mp;
    size_t vec_len = nums.size();
    for(size_t i = 0; i < vec_len; ++i) {
        int diff = target - nums[i];
        unordered_map<int, int>::iterator it = mp.find(diff);
        if((it != mp.end()) && (i != it->second)) {    // 确保不重复使用同一元素
            ret.push_back(it->second);
            ret.push_back(i);
            break;
        }
        mp[nums[i]] = i;
    }
    return ret;
}

算法真实毒打我,解决问题我可,提高效率实难emmm

继续加油吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值