LeetCode第一题,刚拿到题目时虽然明知道n方的遍历算法会超时,但还是不信邪的提交了一次,然而编程不存在运气,TLE不可避免。但是之后的思维方式比较直接,我并没有立刻想到O(n)的方法,想了一种先对数组进行排序,利用目标数和待选择的数的关系来减小搜索范围:

1.不存在负数:那么比目标数大的数不必搜索

2.存在负数:搜索负数和比目标大的数,或者搜索正数比目标小的数;这种情况还存在全为负数,只能按照最差的n方方式搜索。

按照这个优化思路,虽然算法严格意义上来说是n方复杂度的,但是实际性能并不一定这么差,以下是AC代码:

/**
* Note: The returned array must be malloced, assume caller calls free().
*/
typedef struct newtype
{
int num;int index;
}Data;
int cmp ( const void *a , const void *b )
{
Data *c = (Data *)a;Data *d = (Data *)b;
if(c->num != d->num)
return c->num - d->num;
else
return d->index - c->index;
} int* twoSum(int* nums, int numsSize, int target) {
int *res,i,j,fuflag=numsSize,bigflag=numsSize;
int tempgflag=;
int tempres;
Data *data=(Data *)malloc(sizeof(Data)*numsSize);
for(i=;i<numsSize;i++)
{
data[i].index=i;
data[i].num=nums[i];
}
res=(int *)malloc(sizeof(int)*);
qsort(data,numsSize,sizeof(Data),cmp);
for(i=;i<numsSize;i++)
{
if(data[i].num<)
fuflag=i;
if(data[i].num<=target)
bigflag=i;
}
//1.无负数,只需到比这个数小的位置
if(fuflag==numsSize)
{
for (i = ; i <=bigflag; i++)
for (j = i+; j <=bigflag; j++)
if (data[i].num + data[j].num == target) {
if (data[i].index > data[j].index) {
res[] = data[j].index + ;
res[] = data[i].index + ;
} else {
res[] = data[j].index + ;
res[] = data[i].index + ;
}
break;
}
}
else//2.有负数,所有数都比这个数大
{ for (i = ; i <= fuflag; i++)
for (j = bigflag + ; j < numsSize; j++)
if (data[i].num + data[j].num == target) {
tempgflag=;
if (data[i].index > data[j].index) {
res[] = data[j].index + ;
res[] = data[i].index + ;
} else {
res[] = data[j].index + ;
res[] = data[i].index + ;
}
break;
}
if(tempgflag==)
{
for (i = fuflag + ; i <= bigflag; i++)
for (j = i + ; j <= bigflag; j++)
if (data[i].num + data[j].num == target) {
tempgflag=;
if (data[i].index > data[j].index) {
res[] = data[j].index + ;
res[] = data[i].index + ;
} else {
res[] = data[j].index + ;
res[] = data[i].index + ;
}
break;
}
}
if (tempgflag == ) {
for (i = ; i <= numsSize; i++)
for (j = i + ; j <= numsSize; j++)
if (data[i].num + data[j].num == target) {
if (data[i].index > data[j].index) {
res[] = data[j].index + ;
res[] = data[i].index + ;
} else {
res[] = data[j].index + ;
res[] = data[i].index + ;
}
break;
}
}
}
return res;
}

n方优化

然而在提交之后看了solution才想到另外两种方法,由于确定是两个数字,所以用目标数减去当前某个数字,然后再在候选数里查找这个数!

可以用二分查找,也可以用hash表。

接下来就是使用C++ STL map来实现这个hash过程。

map的使用主要包括声明,赋值,查找,使用迭代器。

声明:

map<int, int> datamap;

赋值:

map遵循<key ,value >的原则,key是不可以重复的!

for(i=;i<n;i++)
datamap[nums[i]]=i;

查找:

map<int,int>::iterator it;

it=datamap.find(target-nums[i]);

使用迭代器:

map的迭代器和vector并不相同,需要使用->来获取元素不能直接使用*

if(it!=datamap.end()&&it->second!=i)

使用map的AC代码:

 class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> datamap;
vector<int> res;
int i;
int n=nums.size();
for(i=;i<n;i++)
datamap[nums[i]]=i;
map<int,int>::iterator it;
for(i=;i<n;i++)
{
it=datamap.find(target-nums[i]);
if(it!=datamap.end()&&it->second!=i)
{
if(i>it->second){
res.push_back(it->second + );
res.push_back(i + ); }
else
{
res.push_back(i + );
res.push_back(it->second + ); }
break;
}
}
return res; }
};

map

本想再试一下hashmap,但是由于并不是标准C++库,所以需要以下头文件和命名空间:

#include <ext/hash_map>
using namespace __gnu_cxx;

才可以在linux上的Eclispe里编译,但是提交发现leetcode的评测环境并不支持以上库,也就没有再试,但是看到网上很多推荐使用unordered_map:

#include <tr1/unordered_map>

使用方法和map,hashmap类似。

PS:

这个题目的数据并不是排好序的!

以下是几组容易wa的测试数据:[-1,-2,-3,-4,-5] -8 ,[0,3,4,0] 0,[-3,4,3,90] 0。

这个题目也是逆向思维的简单应用,并不需要复杂的算法和精妙的构思,反转一下足够。

Two Sum-n方优化与C++map的使用的更多相关文章

  1. 动态规划:部分和问题和数字和为sum的方法数

    很久之前看过这个题目,但是没有仔细整理,直到现在看基础才想到这两个题.这两个题非常经典也非常类似.接下来分别介绍. 部分和问题 题目描述 给定整数a1.a2........an,判断是否可以从中选出若 ...

  2. 数字和为sum的方法数

    [编程题] 数字和为sum的方法数 给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数. 当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案. 输入描 ...

  3. Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP

    E. Product Sum   Blake is the boss of Kris, however, this doesn't spoil their friendship. They often ...

  4. for循环实战性能优化之使用Map集合优化

           笔者在<for循环实战性能优化>中提出了五种提升for循环性能的优化策略,这次我们在其中嵌套循环优化小循环驱动大循环的基础上,借助Map集合高效的查询性能来优化嵌套for循环 ...

  5. hive优化,控制map、reduce数量

    一.调整hive作业中的map数 1.通常情况下,作业会通过input的目录产生一个或者多个map任务.主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为1 ...

  6. 基于visual Studio2013解决面试题之0710求方优化

     题目

  7. MySQL巧用sum,case...when...优化统计查询

    最近在做项目,涉及到开发统计报表相关的任务,由于数据量相对较多,之前写的查询语句查询五十万条数据大概需要十秒左右的样子,后来经过老大的指点利用sum,case...when...重写SQL性能一下子提 ...

  8. 数字和为sum的方法数(动态规划)

    题目描述 给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数.当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案. 输入描述: 输入为两行: 第一行为 ...

  9. AtCoder3857:Median Sum (Bitset优化背包&&对称性求中位数)

    Median Sum You are given N integers A1, A2, ..., AN. Consider the sums of all non-empty subsequences ...

随机推荐

  1. 转:CI伪静态化

    去掉php框架CI默认url中的index.php 2010-03-17 17:33:07|  分类: php框架ci |字号 订阅   CI默认的rewrite url中是类似这样的,例如你的CI根 ...

  2. 转: linux文件链接(软链接和硬链接)

    链接:一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法. Linux中包括两种链接:硬链接(Hard Link)和软链接(Soft Link),软链接又称为符号链接(Symbolic l ...

  3. Hadoop2.0安装

    http://blog.csdn.net/samhacker/article/details/18802223 http://blog.csdn.net/crazyhacking/article/de ...

  4. delete了,析构函数却没有调用

    析构函数在对象的生命结束时,会自动调用,大家所熟知的智能指针就是根据析构函数的这种特性而实现的,包括Qt的内存管理机制,也都是利用了析构函数的这一机制来实现的.c++创始人Bjarne Stroust ...

  5. Html 小插件3

    搜狗搜索框代码 <script>function verifyquery(form){if(form.sogou_drop.value==2){form.insite.value='';} ...

  6. div图片垂直居中

    div相对与table对于图片的垂直居中支持的并不好,特别对于不同浏览器的兼容性来说,这里我们看下一个简洁的css解决方法: 在曾经的 淘宝UED 招聘 中有这样一道题目: “使用纯CSS实现未知尺寸 ...

  7. TCP/IP笔记 三.运输层(2)——TCP 流量控制与拥塞控制

    TCP 的流量控制与拥塞控制可以说是一体的.流量控制是通过滑动窗口实现的,拥塞避免主要包含以下2个内容: (1)慢开始,拥塞避免 (2)快重传,快恢复 1.流量控制——滑动窗口 TCP采用大小可变的滑 ...

  8. MVC模式和URL访问

    一.什么是MVC //了解 M -Model 编写model类 对数据进行操作 使用Model类 来操作数据 V -View 编写html文件,页面呈现 C -Controller 编写类文件(Use ...

  9. js正则验证"汉字"

    var nickname = value; var regex = new RegExp("^([\u4E00-\uFA29]|[\uE7C7-\uE7F3]|[a-zA-Z0-9_]){1 ...

  10. node.weiChat

    微信的朋友圈分享是现在流行的推广模式,最近两天尝试了一下使用微信进行商品的分享,分享结束后我可以在自己的数据库中查询到用户是否分享成功,包括用户使用微信进行支付时的成功验证.个人觉得微信上的教程有些绕 ...