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. 数字运算、ASCII

    num20 = dollar/20;num10 = (dollar - 20*num20)/10;num5 =(dollar-20*num20-10*num10)/5;//可以写为num5 = (do ...

  2. 【原创】Libjpeg 库使用心得(一) JPEG图像DCT系数的获取和访问

    [原创]继续我的项目研究,现在采用Libjpeg库函数来进行处理,看了库函数之后发现C语言被这些人用的太牛了,五体投地啊...废话不多说,下面就进入正题. Libjpeg库在网上下载还是挺方便的,这里 ...

  3. hdu 2565 放大的X

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2565 这个题很简单 但是很容易错,写来给自己一个警示把 首先在最后一个x后面没有空格,然后就是那个换行一 ...

  4. Windows 7各版本的主要功能区别是什么 有何不同

    Windows 7包含6个版本,分别为Windows 7 Starter(初级版).Windows 7 Home Basic(家庭普通版).Windows 7 Home Premium(家庭高级版). ...

  5. Android学习路径图

    一个PHPer转战Android学习过程: 直接跨过java的学习,原因有我之前看过毕向东和张孝祥的Java基础课程,虽然中间好几次看睡着,但java的环境是能跑起来的.我建议大家如果没有Java基础 ...

  6. 如何使用Excel和Word编辑和打印条形码

    本文介绍如何使用Microsoft Office Excel 2007和Microsoft Office Word 2007进行条形码的编辑后,通过普通的办公打印机将条形码打印出来. 对于少量,简单的 ...

  7. QTabWiget Change Color 改变颜色(每个QWidget都有一个自己的调色板palette,设置它的颜色,然后setAutoFillBackground即可)

    Qt中的QTabWiget 类提供了一个便签控件,但是这个控件默认初始化的颜色是白色,和原窗口的颜色不同,看起来非常的违和,所以我们希望将其的背景颜色设为当前窗口的背景颜色.我们所要做的就是先将应用程 ...

  8. CDialogSK - A Skinnable Dialog Class

    Introduction This class is derived from the MFC CDialog. It supports the following features :- If ru ...

  9. orcale装完sqldevelop启动不了

    一直在搞考试,昨天考java企业级开发要交项目搞得我装系统后又装了个orcale,每次重新配百度太麻烦,还好记得点,记录下碰到的错误 64位的系统下的orcale11 64位里面的sqldevelop ...

  10. UI基础:UILabel.UIFont

    UILabel:标签 继承自UIView ,在UIView基础上扩充了显示文本的功能.(文本框) UILabel的使用步骤 1.创建控件 UILabel *aLabel=[[UILabel alloc ...