LeetCode题解——Two Sum
题目地址:https://oj.leetcode.com/problems/two-sum/
Two Sum
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
题目大意:
给定一个数组,找出其中两个数,它们的和等于给定的值。
函数返回这两个数的“下标”,下标按序排列,从1开始计算。
每个输入有且只有一个解。
分析:
①暴力解法。
求每两个元素的和,时间为O(n2)。
②先排序,后查找 或者 左右夹逼。
排序时间O(n logn),由于需要记录下标和元素值的关系,空间复杂度O(n)。然后:
查找:对每一个元素a,二分查找target - a是否存在。总时间为O(n logn) + O(n logn) = O(n logn);
夹逼:利用一对首尾指针求和,和<target,则首指针右移;和>target,则尾指针左移;相等则返回记录的下标值。总时间为O(n logn) + O(n) = O(n logn)。
③利用哈希表查找。
哈希表记录元素对应下标,对于元素a,O(1)时间查找target - a是否存在。总时间为O(n)。
程序挂掉的几个测试用例:
[5, 75, 25] 100 //排序之后下标顺序问题
[3, 2, 4] 6 //3 + 3 == 2 + 4 同一个元素被计算两次
[0, 4, 3, 0] 0 //0 + 0 元素重复,哈希表覆盖
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <tr1/unordered_map>
using namespace std;
using namespace tr1; //②先排序,再夹逼。用一个辅助struct来记录数据和下标信息,并自定义比较函数,来对struct数组排序。
struct node{
int data;
int index;
node(int _data, int _index): data(_data), index(_index)
{
}
}; bool myCmp(node n1, node n2)
{
return n1.data < n2.data;
} vector<int> twoSum1(const vector<int> &numbers, int target)
{
vector<int> result; if(numbers.empty())
{
return result;
} vector<node> nv; //space: O(N)
for(int i = ; i < numbers.size(); ++i) //time: O(N)
{
nv.push_back( node(numbers[i], i) );
} sort(nv.begin(), nv.end(), myCmp); //排序,time: O(NlgN) int hIdx = , tIdx = nv.size() - ; while(hIdx < tIdx) //夹逼,time: O(N)
{
int sum = nv[hIdx].data + nv[tIdx].data; if(sum == target)
{
result.push_back(min(nv[hIdx].index, nv[tIdx].index) + );//min、max来确保下标顺序
result.push_back(max(nv[hIdx].index, nv[tIdx].index) + );
break;
}
else if(sum < target)
{
++hIdx;
}
else
{
--tIdx;
}
} //while return result;
} //③哈希表,由数据映射到下标,相同数据只记录最后一个下标。
vector<int> twoSum2(const vector<int> &numbers, int target)
{
vector<int> result; if(numbers.empty())
{
return result;
} unordered_map<int, int> num2loc; //space: O(N)
for(int i = ; i < numbers.size(); ++i) //哈希映射,time: O(N)
{
num2loc[ numbers[i] ] = i;
} for(int i = ; i < numbers.size() - ; ++i) //查找,time: O(N)
{
int gap = target - numbers[i]; if( num2loc.find(gap) != num2loc.end() && num2loc[gap] > i )
{
result.push_back(i + );
result.push_back(num2loc[gap] + );
break;
}
} return result;
} int main()
{
int nums[] = {,,,};
vector<int> numbers(nums, nums + sizeof(nums)/sizeof(*nums));
int target = ; vector<int> result; result = twoSum1(numbers, target);
for(int i = ; i < result.size(); ++i)
{
cout << result[i] << ' ';
}
cout << endl; result = twoSum2(numbers, target);
for(int i = ; i < result.size(); ++i)
{
cout << result[i] << ' ';
}
cout << endl; return ;
}
LeetCode题解——Two Sum的更多相关文章
- [LeetCode 题解] Combination Sum
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a se ...
- [LeetCode 题解]: Two Sum
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given an a ...
- LeetCode题解之Sum Root to Leaf Numbers
1.题目描述 2.问题分析 记录所有路径上的值,然后转换为int求和. 3.代码 vector<string> s; int sumNumbers(TreeNode* root) { tr ...
- 回溯法 leetcode题解 Combination Sum 递归法
题目大意:给出一个数组,用这些数组里的元素去凑一个target.元素可以重复取用. 感觉对这种题目还是生疏的.脑子里有想法,但是不知道怎么表达出来. 先记录下自己的递归法.应该还可以用循环实现. 回溯 ...
- LeetCode题解之 Sum of Left Leaves
1.题目描述 2.问题分析 对于每个节点,如果其左子节点是叶子,则加上它的值,如果不是,递归,再对右子节点递归即可. 3.代码 int sumOfLeftLeaves(TreeNode* root) ...
- [LeetCode 题解]:Path Sum
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a bi ...
- [LeetCode] #167# Two Sum II : 数组/二分查找/双指针
一. 题目 1. Two Sum II Given an array of integers that is already sorted in ascending order, find two n ...
- [LeetCode] #1# Two Sum : 数组/哈希表/二分查找/双指针
一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of ...
- 【LeetCode题解】二叉树的遍历
我准备开始一个新系列[LeetCode题解],用来记录刷LeetCode题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有 ...
随机推荐
- Linux与Windows中动态链接库的分析与对比
摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系 ...
- eclipse/MyEclipse 日期格式、注释日期格式、时区问题
eclipse/MyEclipse 日期格式.注释日期格式.时区问题 在eclipse/MyEclipse中,如果你的注释或是运行System.out.print(new java.util.Date ...
- Web网站架构设计
目录 [隐藏/显示] 1 - Web负载均衡 1.1 - 使用商业硬件实现 1.2 - 使用开源软件 1.3 - 使用windows自带的互载均衡软件 1.4 - 总结2 - 静态网站 ...
- uva 437 hdu 1069
dp 将石块按三个面存入队列 按底面积排序 dp就最大高度 按嵌套矩形最长路做做法 #include <iostream> #include <cstdio> #inc ...
- discuz云平台报调用远程接口失败的问题分析和解决
根据网络两篇文章整理 问题描述:当开通或关闭某个云平台服务的时候,报如下错误信息:调用远程接口失败.请检查您的服务器是否处于内网以及您服务器的防火墙设置. 云平台测试站点的接口文件正常,于是开始在文件 ...
- ValueError: Attempted relative import in non-package
执行:python deom/scripts/populate.py ValueError: Attempted relative import in non-package solve:python ...
- hdu 3400 Line belt 三分法
思路:要求最短时间从A到D,则走的路线一定是AB上的一段,CD上的一段,AB与CD之间的一段. 那么可以先三分得到AB上的一个点,在由这个点三分CD!! 代码如下: #include<iostr ...
- Qt: 访问容器(三种方法,加上for循环就四种了)good
#include <iostream>#include <QString>#include <QList>#include <QListIterator> ...
- POJ2635——The Embarrassed Cryptographer(高精度取模+筛选取素数)
The Embarrassed Cryptographer DescriptionThe young and very promising cryptographer Odd Even has imp ...
- python脚本工具-2 去除扩展名后提取目录下所有文件名并保存
文件夹里有多个RM格式的视频文件,现需要把它们的文件名都提取出来,并去掉文件的扩展名,以便放到需要的网页里. 源代码: # --- picknames.py --- import os filenam ...