2018.11.9 《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门
这道题挺简单的,只要设置两个指针left和right,分别从数组头尾出发找满足条件的两个数字。若两数之和大于S,则right右移;若两数之和小于S,则left右移。乘积最小的两个数即为最先找到的两个数(越往中间乘积越大,不管对于正数数组、负数数组还是有正有负,结论都是一样的)。
题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
Java实现:
/**
*
* @author ChopinXBP
* 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S。
* 如果有多对数字的和等于S,输出两个数的乘积最小的。
*
*/
import java.util.ArrayList;
public class FindNumbersWithSum_40 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = { 1, 2, 4, 5, 7, 8, 15 };
ArrayList<Integer> result = FindNumbersWithSum(array, 13);
System.out.println(result.get(0) + " " + result.get(1));
}
public static ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
if (array == null)
return null;
ArrayList<Integer> result = new ArrayList<>(2);
int left = 0;
int right = array.length - 1;
while (left < right) {
int num1 = array[left];
int num2 = array[right];
if (num1 + num2 == sum) {
result.add(num1);
result.add(num2);
break;
} else if (num1 + num2 < sum) {
left++;
} else if (num1 + num2 > sum) {
right--;
}
}
return result;
}
}
C++实现示例:
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> result;
int length = array.size();
int start = 0;
int end = length - 1;
while (start < end)
{
if (array[start] + array[end] == sum)
{
result.push_back(array[start]);
result.push_back(array[end]);
break;
}
else if (array[start] + array[end] < sum)
start++;
else
end--;
}
return result;
}
};
测试代码:
// ====================测试代码====================
void Test(char* testName, int data[], int length, int sum, bool expectedReturn)
{
if(testName != NULL)
printf("%s begins: ", testName);
int num1, num2;
int result = FindNumbersWithSum(data, length, sum, &num1, &num2);
if(result == expectedReturn)
{
if(result)
{
if(num1 + num2 == sum)
printf("Passed. \n");
else
printf("Failed. \n");
}
else
printf("Passed. \n");
}
else
printf("Failed. \n");
}
// 存在和为s的两个数字,这两个数字位于数组的中间
void Test1()
{
int data[] = {1, 2, 4, 7, 11, 15};
Test("Test1", data, sizeof(data) / sizeof(int), 15, true);
}
// 存在和为s的两个数字,这两个数字位于数组的两段
void Test2()
{
int data[] = {1, 2, 4, 7, 11, 16};
Test("Test2", data, sizeof(data) / sizeof(int), 17, true);
}
// 不存在和为s的两个数字
void Test3()
{
int data[] = {1, 2, 4, 7, 11, 16};
Test("Test3", data, sizeof(data) / sizeof(int), 10, false);
}
// 鲁棒性测试
void Test4()
{
Test("Test4", NULL, 0, 0, false);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
return 0;
}
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#