1.两数之和

(写给未来遗忘的自己)

 1.暴力破解法

直接两个for循环,直接加

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target)
     {
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return {i, j};
                }
            }
        }
        return {};
    }
};

2.利用std::undered_map来计算  

class Solution {
public:
    std::vector<int> twoSum(std::vector<int>& nums, int target) {
        std::unordered_map<int, int> indexMap;
        std::vector<int> result;

        for (int i = 0; i < nums.size(); ++i) {
            int complement = target - nums[i];
            auto it = indexMap.find(complement);
            if (it != indexMap.end()) {
                // 找到匹配的元素
                result.push_back(it->second);
                result.push_back(i);
                return result;
            }
            indexMap[nums[i]] = i;
        }

        // 如果没有找到匹配的元素,可以抛出异常或返回一个错误状态
        throw std::runtime_error("No two sum solution");
    }
};

 使用同样的map类型的哈希数表,map的三种具体实现写在文末。

思路:

1.我直到结果target,那我在遍历到的值知道,相当于查找一个差值是否存在,当用到查找的时候就考虑哈希数表(数组,set,map) std::undered_map 的查找和删除复杂度O(1)。

2.将遍历过的值作为key,下标作为值存储。当前值和遍历过存储的值中寻找是否有满足的。std::undered_map的Key不允许重复,尽管例如[3,3],当遍历nums[1]的时候,其还没有放进去,所以不影响。

#一个错误的方法 std::multiset

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::multiset<int>nums_set(nums.begin(),nums.end());
        vector<int>input;
        int table=0;
        int two_num,one_num;
        for(int num:nums_set ){
            two_num=target-num;
            one_num=num;
           if(nums_set.find(two_num)!=nums_set.end()){
             table=1;
              break;
           }
        }
        if(table==1){
            for(int j=0;j<nums.size();j++)
            {
                if(nums[j]==one_num){
                    input.push_back(j);
                }
                if(nums[j]==two_num){
                    input.push_back(j);
                }
                if(input.size()==2){
                    break;
                }
            }
        }
         return input;
    }
};

原因:一开始选择的原因是 哈希数表的查询速度快,另外两种set都不允许重复的数,这个允许。

但是存在关键问题:

  1. 使用 std::multiset 会改变原始数组的顺序,因此你不能直接从 multiset 中找到原始数组中的索引。(所以需要找到数后继续回去vector里面找下标)

  2. 在查找匹配项时,没有检查是否使用了相同的元素两次(即 one_numtwo_num 是否在原数组中为同一位置的元素)。

  3. 当找到匹配对时,循环可能不会正确地返回第一个匹配对的索引,因为 std::multiset 不保证保持元素的插入顺序。(这个就是第一个的附带问题)

———————————————————————————————————————————map的使用方法: 

      1. std::map

  • 数据结构:基于红黑树,键值对是有序的。(根据键的值排序的,由于使用的红黑树,所以可以二分查找
  • 插入操作:如果键已存在,插入失败,不会覆盖已存在的键值对。
  • 查找效率:对数时间复杂度(O(log n)),因为树的结构。
  • 迭代器:提供稳定且连续的迭代器,可以按升序遍历键值对
  • std::map<std::string, int> myMap;
    myMap["apple"] = 1;
    myMap["banana"] = 2;

    2. std::unordered_map

  • 数据结构:基于哈希表,键值对是无序的(哈希表通过计算键的哈希值来确定键值对的存储位置)。
  • 插入操作:如果键已存在,插入失败,但如果使用 insert 方法并提供一个键值对,可以设置是否覆盖已存在的值。
  • 查找效率:平均情况下的常数时间复杂度(O(1)),但最坏情况是线性的(O(n)),取决于哈希函数和冲突处理策略。
  • 迭代器:不保证迭代器的稳定性,因为元素的位置可能由于重新哈希而变化。
std::unordered_map<std::string, int> myUnorderedMap;
myUnorderedMap["apple"] = 1;
myUnorderedMap["banana"] = 2;

3. std::multimap

  • 数据结构:与 std::map 类似,基于红黑树,键值对是有序的。
  • 插入操作:允许同一个键有多个值,形成键值对的集合。
  • 查找效率:对数时间复杂度(O(log n)),与 std::map 相同。
  • 迭代器:提供稳定且连续的迭代器,可以按升序遍历键值对。
std::multimap<std::string, int> myMultimap;
myMultimap.insert({"apple", 1});
myMultimap.insert({"apple", 2});
myMultimap.insert({"banana", 3});

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值