栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > C/C++/C#

【LeetCode作业本】1. 两数之和

C/C++/C# 更新时间:发布时间: 百科书网 趣学号

【LeetCode作业本】1. 两数之和
  • 一、题目:两数之和
  • 二、解题思路
    • 1.暴力枚举
    • 2.字典/哈希表
  • 三、C++哈希表
    • 1. map
    • 2. hash_map
    • 3.unordered_map

一、题目:两数之和

原链接:https://leetcode.cn/problems/two-sum/
难度:简单

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

示例一:

输入: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
  • 只会存在一个有效答案

进阶: 你可以想出一个时间复杂度小于 O(n2) 的算法吗?

二、解题思路 1.暴力枚举

很容易想到两层for循环(写出来也木得工作)。第一层从i开始,第二层从i+1开始。

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

复杂度分析:
· 时间复杂度:O(N2)。
· 空间复杂度:O(1)。
可以看到第二层的遍历有些浪费,可以通过字典记录下来。

2.字典/哈希表

暴力枚举时间复杂度较高的原因是寻找 target - nums[i] 的时间复杂度过高。使用哈希表,可以将寻找 target - nums[i]的时间复杂度降低到从 O(N) 降低到 O(1)。

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        map m;
        for(int i=0; i < nums.size(); i++){
            auto it = m.find(target - nums[i]);
            //cout<second<
                return {i, it->second};
            }
            m[nums[i]] = i;
        }
        return {};
    }
};

复杂度分析:
· 时间复杂度:O(N2)。
· 空间复杂度:O(1)。

三、C++哈希表 1. map

底层是红黑树,该结构具有自动排序的功能,因为红黑树本来就是一种二叉搜索树,所以从begin()遍历到end()得到的key值是有序的,这也是map的一个特点。
空间复杂度为O(n) 随着节点的增加才增加。
查找的时间时间复杂度 则固定是O(log(n))。
优点:有序性。
缺点:空间占用高。

2. hash_map

hash_map基于hash table(哈希表)。
优点:数据的存储和查找消耗的时间低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然而在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的。另外,编码比较容易也是它的特点之一。
查找的时间复杂度可以达到O(1),基本上都是比map快的。

hash_map,首先分配一大片内存,形成许多桶。是利用hash函数,对key进行映射到不同区域(桶)进行保存。其插入过程是:

3.unordered_map

最初的 C++ 标准库中没有类似 hash_map 的实现,但不同实现者自己提供了非标准的 hash_map。 因为这些实现不是遵循标准编写的,所以它们在功能和性能保证方面都有细微差别。从 C++ 11 开始,hash_map 实现已被添加到标准库中。但为了防止与已开发的代码存在冲突,决定使用替代名称 unordered_map。这个名字其实更具描述性,因为它暗示了该类元素的无序性。而且unordered_map已经成为标准,不建议再使用hash_map。

hash_map是SGI实现,而unordered_map是C++11标准中新增的。虽然大多数情况下hash table实现的map都会比红黑树实现的map查找快,但不是绝对的,因为冲突过多的话,可能耗费时间比map还要多。所以对于前者基本上都会有个rehash的操作,而由于rehash的处理不一样,也导致了hash_map和unordered_map的性能有一些差别。hash_map的rehash简单粗暴,直接就是更新bucket数目为需要的数目就行了,而不会像unordered_map那样子进行数量的优化。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/1043098.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号