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 ...
随机推荐
- linux下查找文件、排序、查看文件内容
本文介绍下,在linux系统中,查找文件的命令用法,以及按时间排序找到的目标文件的方法. 1.例如:查找当前目录下所有.ini文件,并按时间排序 示例: find ./ -name *.ini ...
- 实现将VirtualBox 虚拟机转换为KVM虚拟机的步骤
原来在桌面上一直使用virtualbox虚拟机管理程序(VMM)构建虚拟机安装不同的操作系统,现在 研究linux下的KVM,能否将已经建立的virtualBox虚拟客户机(guest)转换为KVM虚 ...
- 探索 Windows Azure 网站中的自动伸缩功能
去年10月,我们发布了若干针对 WindowsAzure平台的更新,其中一项更新是添加了基于日期的自动伸缩调度支持(在不同的日期设置不同的规则). 在这篇博客文章中,我们将了解自动伸缩的概念,并 ...
- UVA - 1103Ancient Messages(dfs)
UVA - 1103Ancient Messages In order to understand early civilizations, archaeologists often study te ...
- android之PackageManager简单介绍
PackageManager相关 本类API是对全部基于载入信息的数据结构的封装,包含下面功能: 安装,卸载应用查询permission相关信息 查询Application相关信息(applicati ...
- Css Rest 方法
在当今网页设计/开发实践中,使用CSS来为语义化的(X)HTML标记添加样式风格是 重要的关键.在设计师们的梦想中都存在着这样的一个完美世界:所有的浏览器都能够理解和适用多有CSS规则,并且呈现相同的 ...
- 浅谈Struts2(一)
一.Struts2引言 1.Struts2框架的概念 解决的MVC开发过程中,控制器(Controller)的通用问题. a.什么是MVC开发 MVC开发是一种编程思想,由设计者人为的把一个项目,划分 ...
- 小猪猪C++笔记基础篇(五)表达式、语句
小猪猪C++笔记基础篇(五) 关键词:表达式.语句 本章的内容比较简单,基本上没有什么理解上的困难,都是知识上的问题.先开始想要不要写呢,本来是不准备写的,但是既然读了书就要做笔记,还是写一写,毕竟还 ...
- Media Queries for Standard Devices
/* Smartphones (portrait and landscape) ----------- */ @media only screen and (min-device-width : 32 ...
- bzoj 1057: [ZJOI2007]棋盘制作 单调栈
题目链接 1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 2027 Solved: 1019[Submit] ...