【LeetCode & 剑指offer刷题】数组题2:57 有序数组中和为s的两个数(167 Two Sum II - Input array is sorted)
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
57 有序数组中和为s的两个数
题目描述
输入一个
递增排序的数组和一个数字S,在数组中
查找两个数,是的他们的和正好是S,如果有多对数字的
和等于S,
输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。
#include <climits>
class
Solution
{
public
:
vector
<
int
>
FindNumbersWithSum
(
vector
<
int
>
a
,
int
sum
)
{
if
(
a
.
size
()<
2
)
return
vector
<
int
>();
int
min_product
=
INT_MAX
;
int
left
=
0
,
right
=
a
.
size
()-
1
;
int
a1
,
a2
;
bool
find_flag
=
false
;
while
(
left
<
right
)
//从两边开始往中间扫描
{
int
cursum
=
a
[
left
]
+
a
[
right
];
if
(
cursum
>
sum
)
right
--;
else
if
(
cursum
<
sum
)
left
++;
else
{
//
因为对于递增序列,一定有
x*y < (x+a)*(y-a)
,故这里其实可以不用判断
//
从两边开始往中间扫描时,找到的第一个即为乘机最小的一对数
if
(
a
[
left
]*
a
[
right
]
<
min_product
)
{
find_flag
=
true
;
min_product
=
a
[
left
]*
a
[
right
];
a1
=
a
[
left
];
a2
=
a
[
right
];
}
left
++;
//
继续扫描
}
}
if
(
find_flag
)
return
vector
<
int
>{
a1
,
a2
};
else
return
vector
<
int
>();
}
};
拓展:和为S的连续正数序列
题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(
至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:
输出所有和为S的连续正数序列(指1、2、3、4等)
。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
class
Solution
{
public
:
vector
<
vector
<
int
>
>
FindContinuousSequence
(
int
sum
)
{
vector
<
vector
<
int
>>
result
;
if
(
sum
<
3
)
return
result
;
//至少需包含两个数
int left = 1, right = 2;
//序列从1开始
while
(
left
<
right
) //注意从开头开始扫描,直到left与right相遇
{
int
cursum
=
(
left
+
right
)*(
right
-
left
+
1
)/
2
;
//用等差数列的求和公式
if
(
cursum
<
sum
)
right
++;
else
if
(
cursum
>
sum
)
left
++;
else
{
vector
<
int
>
temp
;
for
(
int
i
=
left
;
i
<=
right
;
i
++)
temp
.
push_back
(
i
);
result
.
push_back
(
temp
);
//push符合要求的连续正数序列
left
++;
//继续下个序列的寻找
}
}
//最后退出循环时,left = right = sum/2+1的位置,比如找10,最后指向 5、6,再均指向6,退出循环
return
result
;
}
};