【LeetCode & 剑指offer刷题】数组题1:Two Sum(系列)
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
1. Two Sum
Given an array of integers, return
indices
of the two numbers such that they add up to a specific target.
You may assume that each input would have
exactly
one solution, and you may not use the
same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[
0
] + nums[
1
] = 2 + 7 = 9,
return [0, 1].
作为LeetCode的首题,Two Sum的名气不小啊,正所谓平生不会TwoSum,刷尽LeetCode也枉然。记得原来在背单词的时候,总是记得第一个单词是abandon,结果有些人背来背去还在abandon,有时候想想刷题其实跟背GRE红宝书没啥太大的区别,都是一个熟练功夫,并不需要有多高的天赋,只要下足功夫,都能达到一个很不错的水平,套用一句鸡汤问来激励下吧,“有些时候我们的努力程度根本达不到需要拼天赋的地步” (来源于博客)
//问题:数组找两个和为目标值的数
//方法一:双重遍历(类似选择排序法中的方法),扫描到所有可能的组合
//O(n^2) O(1) 很慢186ms
/*
class Solution
{
public:
vector twoSum(vector& a, int target)
{
for(int i = 0; i < a.size()-1; i++)
{
for(int j = i+1; j
{
if(a[i]+a[j] == target) return vector{i,j};
}
}
return vector{-1,-1}; //表示没有找到
}
};*/
/*
方法二:一次遍历+hash表
过程:将值+索引存储在hash表中,每次查找hash表中是否存在某个key(target-a[i],用成员函数find查找即可,每次查找花费常数时间)与当前值和为target
O(n), O(n) 14ms
*/
#include
class
Solution
{
public
:
vector
<
int
>
twoSum
(
vector
<
int
>&
a
,
int
target
)
{
unordered_map
<
int
,
int
>
table
;
vector
<
int
>
result
;
for
(
int
i
=
0
;
i
<
a
.
size
();
i
++)
//遍历数组
{
//先找再存,这样有先后关系,在已经存的元素中去找可以凑成2sum对的元素,防止同一个数被使用两次
int
numberToFind
=
target
-
a
[
i
];
//算出要找的值,
if
(
table
.
find
(
numberToFind
)
!=
table
.
end
())
//如果找得到(当找不到的时候,find函数会返回容器的末尾迭代器)
{
result
.
push_back
(
table
[
numberToFind
]); //push索引,因为要返回索引
result
.
push_back
(
i
);
}
else
//如果找不到时,存入hash表
table
[
a
[
i
]]
=
i
;
//值+索引(key-value)存于hash表中,相同的元素会覆盖前面的索引
//哈希表无需手动重建空间,当调用[]符号时会自动创建空间,并赋初始值0(如果不手动赋值的话)
}
return
result
;
}
};
167. Two Sum II - Input array is sorted(《剑指offer》第57题)
Given an array of integers that is already sorted in ascending order, 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.
Note:
-
Your returned answers (both index1 and index2) are not zero-based.
-
You may assume that each input would have exactly one solution and you may not use the same element twice.
Example:
Input:
numbers = [2,7,11,15], target = 9
Output:
[1,2]
Explanation:
The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
/*
问题:所给数组为有序数组(递增),找和为特定值的两个数
方法:双指针法
过程:前后各一指针,当和小于target时,往中间移动左边指针,当和大于target时,往中间移动右边指针直到相遇或者等于target
O(n), O(1) (由于利用了数组有序性的特点,优于哈希表的方法)
*/
class
Solution
{
public
:
vector
<
int
>
twoSum
(
vector
<
int
>&
a
,
int
target
)
{
vector
<
int
>
result
;
if
(
a
.
empty
())
return
result
;
int left = 0, right = a.size()-1;
while
(
left
<
right
)
{
if
(
a
[
left
]
+
a
[
right
]
<
target
)
left
++;
else
if
(
a
[
left
]
+
a
[
right
]
>
target
)
right
--;
else
{
result
.
push_back
(
left
+
1
);
//题目要求索引以1开始
result
.
push_back
(
right
+
1
);
return
result
;
}
}
return
result
;
}
};
653
.
Two Sum IV - Input is a BST
Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.
Example 1:
Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
Output:
True
Example 2:
Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 28
Output:
False
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/*
问题:在BST中找two sum的两个数,判断是否存在
方法:中序遍历后查找即可
O(n) O(n)(因为每个结点都会被访问一次,故会有n次递归,递归栈的空间复杂度为o(n))
*/
class
Solution
{
public
:
bool
findTarget
(
TreeNode
*
root
,
int
k
)
{
vector
<
int
>
a
;
//用于存结点值
inorder
(
root
,
a
);
int
left
=
0
,
right
=
a
.
size
()-
1
;
while
(
left
<
right
)
{
int
sum
=
a
[
left
]
+
a
[
right
];
if
(
sum
<
k
)
left
++;
else
if
(
sum
>
k
)
right
--;
else
return
true
;
}
return
false
;
}
private
:
void
inorder
(
TreeNode
*
root
,
vector
<
int
>&
a
)
{
if
(
root
==
nullptr
)
return
;
inorder
(
root
->
left
,
a
);
a
.
push_back
(
root
->
val
);
inorder
(
root
->
right
,
a
);
}
};
posted @
2019-01-05 13:34 wikiwen 阅读(
...) 评论(
...) 编辑 收藏