题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
解题思路
- 利用
双指针
把数组中的每个元素拿出来与其后面的所有元素分别作和,用if条件句
来判断是否满足条件 - 易错点:
j=i+1
(要从每个查找的元素后一个开始进行循环)注:j = 0
与i != j
一起使用也可以
Cpp实现
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for(int i = 0;i<nums.size();i++){
for(int j = i + 1;j<nums.size();j++){
if(nums[i] + nums[j] == target)
return {i,j};
}
}
return {};
}
};
Python实现
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i + 1,len(nums)):
if nums[i] + nums[j] == target:
return i,j
C#实现
public class Solution {
public int[] TwoSum(int[] nums, int target) {
int[] result = new int[2];
for(int i = 0;i<nums.Length;i++){
for(int j = i + 1;j<nums.Length;j++){
if(nums[i] + nums[j] == target){
result[0] = i;
result[1] = j;
}
}
}
return result;
}
}
- 时间复杂度:O(n^2)
Java实现
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i = 0;i < nums.length - 1;i++){
for(int j = i + 1;j < nums.length;j++){
if(nums[i] + nums[j] == target){
return new int[]{i,j};
}
}
}
return new int[0];
}
}
- 时间复杂度:O(n ^ 2)
解题思路
哈希表
-
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
-
哈希表
hashtable(key,value)
就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。(或者:把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。)
而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位。 -
Hash Table的查询速度非常的快,几乎是O(1)的时间复杂度。
-
两遍哈希表:(先向map中添加元素再查找)
Cpp实现
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int>m;
for(int i = 0;i < nums.size();i++)
m[nums[i]] = i;//哈希函数,无冲突
for(int j = 0;j < nums.size();j++){
if(m.find(target - nums[j]) != m.end() && m[target - nums[j]] != j){
return {j,m[target - nums[j]]};//哈希表中存在且不等于自身
}
}
return {};
}
};
Python实现
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap = {}
for i,m in enumerate(nums):
hashmap[m] = i
for i,m in enumerate(nums):
j = hashmap.get(target - m)
if j is not None and i != j:
return i,j
-
时间复杂度:O(n)
-
一遍哈希表:(边向map中添加元素边查找)
Cpp实现
class Solution
{public: vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++){
if(m.find(target-nums[i])!=m.end())
return {m[target-nums[i]],i};
//先返回的是m[target-nums[i]]后返回的是i
//查找的顺序是从第i个往前查找
//所以找到m[target-nums[i]]的键值比i小
m[nums[i]]=i;
}
return {};
}
};
Python实现
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap = {}
for i,m in enumerate(nums):
if hashmap.get(target - m) is not None:
return hashmap.get(target - m),i
hashmap[m] = i
- 时间复杂度:O(n)
Java实现
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i = 0;i < nums.length;i++){
if(map.containsKey(target - nums[i])){
return new int[]{map.get(target - nums[i]),i};
}
map.put(nums[i],i);
}
return new int[0];
}
}
- 时间复杂度:O(n)
易错代码示范
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left < right){
if(nums[left] + nums[right] == target)
return {left,right};
else if(nums[left] + nums[right] < target)
left++;
else
right--;
}
return {};
}
};
错误原因:对于由小到大排列好的数组,我们可以用这种方法