Two Sum-n方优化与C++map的使用
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的使用的更多相关文章
- 动态规划:部分和问题和数字和为sum的方法数
很久之前看过这个题目,但是没有仔细整理,直到现在看基础才想到这两个题.这两个题非常经典也非常类似.接下来分别介绍. 部分和问题 题目描述 给定整数a1.a2........an,判断是否可以从中选出若 ...
- 数字和为sum的方法数
[编程题] 数字和为sum的方法数 给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数. 当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案. 输入描 ...
- 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 ...
- for循环实战性能优化之使用Map集合优化
笔者在<for循环实战性能优化>中提出了五种提升for循环性能的优化策略,这次我们在其中嵌套循环优化小循环驱动大循环的基础上,借助Map集合高效的查询性能来优化嵌套for循环 ...
- hive优化,控制map、reduce数量
一.调整hive作业中的map数 1.通常情况下,作业会通过input的目录产生一个或者多个map任务.主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为1 ...
- 基于visual Studio2013解决面试题之0710求方优化
题目
- MySQL巧用sum,case...when...优化统计查询
最近在做项目,涉及到开发统计报表相关的任务,由于数据量相对较多,之前写的查询语句查询五十万条数据大概需要十秒左右的样子,后来经过老大的指点利用sum,case...when...重写SQL性能一下子提 ...
- 数字和为sum的方法数(动态规划)
题目描述 给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数.当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案. 输入描述: 输入为两行: 第一行为 ...
- AtCoder3857:Median Sum (Bitset优化背包&&对称性求中位数)
Median Sum You are given N integers A1, A2, ..., AN. Consider the sums of all non-empty subsequences ...
随机推荐
- 每天一个小算法(5)----找到链表倒数第K个结点
估计这个问题在面试中被问烂了. 思路是先找到正数的第K个结点的指针pT,然后和指向头结点的指针pN一起向后移动,直到第K个指针指向NULL,此时pN指向的结点即倒数第K个结点. 如图: #includ ...
- Cortex-M3 动态加载二(RWPI数据无关实现)
上一篇关于动态加载讲述的是M3下面的ropi的实现细节,这一篇则讲述RW段的实现细节以及系统加载RW段的思路,我在M3上根据这个思路可以实现elf的动态加载,当然进一步的可以优化很多东西,还可以研究将 ...
- 大数据技术 vs 数据库一体机[转]
http://blog.sina.com.cn/s/blog_7ca5799101013dtb.html 目前,虽然大数据与数据库一体机都很火热,但相当一部分人却无法对深入了解这两者的本质区别.这里便 ...
- c++ 学习笔记(常见问题与困惑)(转载)
本问转自: http://www.cnblogs.com/maowang1991/p/3290321.html 1.struct成员默认访问方式是public,而 class默认访问方式是privat ...
- SQL Server 数据类型陷阱
1. bit 类型:bit(1) 不要以为它只占一个位,事实上它要占一个字节!也就是说当n < 8 时都是这样的! 2. varchar(n) 这里的n不能大于8000,如果想要比8000大你 ...
- javascript简单对象创建
由于javascript中定义了一个函数就相当于定义了一个类,我们当然可以创建一个这个类的对象. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 ...
- php正则表达式的基本语法
简单的说,正则表达式是一种可以用于模式匹配和替换的强有力的工具.我们可以在几乎所有的基于UNIX系统的工具中找到正则表达式的身影,例 如,vi编辑器,Perl或PHP脚本语言,以及awk或sed sh ...
- Struts2 学习笔记20 类型转换part2 写自己的转换器
之前说的是调用Struts2的默认转换器,现在我们来说以下写自己的转换器,这个一般不常用,在访问不是自己写的类中可能用到.我们一点点来,因为写自己的转换器需要注意的东西还是很多的. 我们还是用之前的项 ...
- Apache Mina开发手冊之四
Apache Mina开发手冊之四 作者:chszs,转载需注明. 博客主页:http://blog.csdn.net/chszs 一.Mina开发的主要步骤 1.创建一个实现了IoService接口 ...
- 【原创】ASP.NET Web开发,实现打印Log日志,步骤详解
添加Log需要四步: 一.引用log4net.dll,详见附件:http://pan.baidu.com/s/1c0hab2g 二.项目根目录下,添加 log4net.xml <?xml ver ...