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. 百度ueditor富文本编辑器的使用

    百度ueditor富文本编辑器的使用 //以下为我在官网下载的ueditor v1.3.5 php版的大楷配置步骤第一步: //配置文件的引入应该比功能文件先引入,最后设置语言类型.即:editor. ...

  2. VC++中的类的内存分布(上)(通过强制转换,观察地址,以及地址里的值来判断)

    0.序 目前正在学习C++中,对于C++的类及其类的实现原理也挺感兴趣.于是打算通过观察类在内存中的分布更好地理解类的实现.因为其实类的分布是由编译器决定的,而本次试验使用的编译器为VS2015 RC ...

  3. Windows Azure 新上线网络相关服务

     动态路由网关.点到站点(Point to Site)VPN正式商用 动态路由网关和点到站点VPN支持基于路由的VPN,并且允许用户将独立计算机连接到Azure上的虚拟网络.现在,虚拟网络中的动态 ...

  4. BZOJ 4503 两个串(FFT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4503 [题目大意] 给出S串和T串,计算T在S中出现次数,T中有通配符'?'. [题解 ...

  5. apache 支持 php

    找到 httpd 的配置文件:一般在 /etc/httpd/conf 编辑:vi httpd.conf 配置 httpd.conf 让apache支持PHP: # vi /usr/local/apac ...

  6. Java 根据comboBox选择结果显示JTable

    处理这样的问题的主要思路是:     对于JTable,JTree等Swing控件,都有一个对应的Model用来存储数据,JTable对应的有一个DefaultTableModel.     Defa ...

  7. Linux2.6中的Slab层

          还记得一个进程创建的时候是什么给它分配的“进程描述符”吗?没错,是slab分配器,那么,这个slab分配器是个什么东西呢?       分配和释放数据结构是所有内核中最普遍的操作之一.为了 ...

  8. 借助树的概率dp(期望)+数学-好题-hdu-4035-Maze

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4035 题目意思: 有n个房间,有n-1条通道连接这n个房间(每两个房间之间有且只有一条路,所以实际上 ...

  9. python wsgi

    什么是wsgi? wsgi是一个web组件的接口防范,wsgi将web组件分为三类:web服务器,web中间件,web应用程序 wsgi基本处理模式为:wsgi Server -> wsgi m ...

  10. using的用法

    1.using指令.using + 命名空间名字.命名空间名字可以是系统本有,也可是自己定义的class. 2.using别名.using + 别名 = 包括详细命名空间信息的具体的类型. 达成条件: ...