leetcode编程笔记(一)——two sum

1. 题目

输入一个数组nums[],根据所给的target(目标数),返回两个元素的索引x、y, 
假定:nums[x]+nums[y]=target且x,y唯一

2. 算法分析

得到目标元素需要将每个元素和其他元素相加计算结果和,通常有如下几种方案

  • 暴力搜索

    显然,通过两个for循环的嵌套可简单实现该目的
    算法复杂度:O( n2 )

  • 夹逼搜索

    • 预处理:将nums[]排序(推荐快速排序) nlogn

      tip: 排序时要注意保存每个value对应的原始index

    • 夹逼:设置两个指针从一头一尾开始搜索 n
      if sum > target right - -
      else if sum < target left ++
      else return[left.index,right.index]

    算法复杂度:O(nlogn)

  • 哈西搜索

    • 将nums[]保存在哈西表中,使用 unordered_multimap

      在STL标准库中提供map,multimap,unordered_map,unordered_multimap
      
      map:搜索通过rb树实现,时间复杂度为O(lgn)
      multimap:一种特殊的map,key值可以重复
      unordered_map:通过哈西表实现,时间复杂度为O(n)
      unordered_multimap:一种特殊的unordered_map,key可以重复

      key:数组的值 value:index
      例: nums[4]=233 key=233,value=4

    • 搜索:对于nums中的每个值num,
      计算complement=target-num。
      if comlement 存在 return[num.value,complement.value]
      else num++
      until 全部数组搜索完毕or已经返回值

      tip: unordered_multimap允许相同的key值,每次搜索返回 第一个元素。

    算法复杂度:O( n <script type="math/tex" id="MathJax-Element-5">n</script>)

3. 源代码

代码在VS2013下实现

  • 夹逼搜索:预处理时我直接使用了以前编写归并排序

vector<int> twoSum(vector<int>& nums, int target)//O(nlgn)
{
    int end = nums.size()-1;
    vector<int> sort;
    for (int t = 0; t <= end; t++)
    {
        sort.push_back(nums[t]);
        sort.push_back(t);//保存原始索引
    }
    mergsort(sort, 0, sort.size()-2);
    int i = 0, j = sort.size() - 2;
    while (i != j&&i<j)
    {
        if ((sort[i] + sort[j]) > target)
            j = j - 2;
        else if ((sort[i] + sort[j]) < target)
            i = i + 2;
        else
        {
            result.push_back(sort[i+1]);
            result.push_back(sort[j+1]);
            break;
        }
    }
    return result;
}

  • 哈西搜索(多个解的情况仍然适用)

vector<int> twoSum1(vector<int>& nums, int target)//O(n)使用哈希表
{
    unordered_multimap<int, int> m_nums;
    for (int i = 0; i<nums.size(); i++)
    {
        m_nums.insert(pair<int,int>(nums[i], i));
    }
    unordered_multimap<int, int>::iterator iter = m_nums.begin();
    unordered_multimap<int, int>::iterator judge;
    while( iter != m_nums.end())
    {
        int temp = target-iter->first;
        judge = m_nums.find(temp);
        int n = m_nums.count(temp);//计算该key值有几个重复的元素
        int i = 0;
        while (judge != m_nums.end() && i < n)
        {
            if ( (judge->second) > (iter->second))//存在
            {
                result.push_back(iter->second);
                result.push_back(judge->second);
                return result;//假定该题目只有唯一解
            }
            judge++;
            i++;
        }
        ++iter;
    }
    return result;
}

此笔记用于自己学习记录,如果有更好的解法和思路,欢迎在文章下指出不足

添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值