题目:输入一个递增排序的数组和一个数字s,在数组中寻找两个数,使得这两个数的和为s。
注意:已经是一个递增排序数组,所以要牢牢得抓住这个特性。
#include <iostream>
using namespace std;
class Solution {
public:
bool FindNumsWithSum(int data[], int length, int sum, int *num1, int *num2) {
if (data == NULL || length <= 1) {
return false;
}
unsigned int head = 0;
unsigned int tail = length -1;
while (head != tail) {
if (data[head]+data[tail] == sum) {
*num1 = data[head];
*num2 = data[tail];
return true;
}
else if (data[head]+data[tail] > sum) {
tail--;
}
else {
head++;
}
}
return false;
}
};
int main(int argc, char const *argv[]) {
int arr[6]= {1,2,4,7,12,15};
const int length = sizeof(arr)/sizeof(arr[0]);
int *num1 = new int;
int *num2 = new int;
Solution s;
bool result = s.FindNumsWithSum(arr, length, 15, num1, num2);
std::cout << result << std::endl;
std::cout << *num1 << " "<< *num2<< std::endl;
delete num1;
delete num2;
return 0;
}
一段错误的代码,主要是参数传递上:
#include <iostream>
using namespace std;
class Solution {
public:
bool FindNumsWithSum(int (&data)[6], int length, int sum, int *num1, int *num2) {
if (data == NULL || length <= 1) {
return false;
}
unsigned int head = 0;
unsigned int tail = length -1;
while (head != tail) {
if (data[head]+data[tail] == sum) {
num1 = &data[head];
num2 = &data[tail];
return true;
}
else if (data[head]+data[tail] > sum) {
tail--;
}
else {
head++;
}
}
return false;
}
};
int main(int argc, char const *argv[]) {
int arr[6]= {1,2,4,7,12,15};
const int length = sizeof(arr)/sizeof(arr[0]);
int *num1 = new int;
int *num2 = new int;
Solution s;
bool result = s.FindNumsWithSum(arr, length, 15, num1, num2);
std::cout << result << std::endl;
std::cout << *num1 << " "<< *num2<< std::endl;
delete num1;
delete num2;
return 0;
}
此段代码会返回 0,0。
原因在于:
num1 = &data[head];
num2 = &data[tail];
data为分配在栈内存的局部遍历,当FindNumsWithSum函数调用结束后,就会销毁该变量,使得num1, num2依旧保存之前的地址,具体的为:
在num1 = &data[head];之前,gdb调试结果为:
(gdb) p num1
$4 = (int *) 0x602010
(gdb) p num2
$5 = (int *) 0x602030
在num1 = &data[head];之后,gdb调试结果为:
(gdb) p num2
$6 = (int *) 0x7fffffffdd40
(gdb) p data[2]
$7 = 4
(gdb) p &data[2]
$8 = (int *) 0x7fffffffdd38
退出FindNumsWithSum之后:
(gdb) p num1
$11 = (int *) 0x602010
(gdb) p num2
$12 = (int *) 0x602030
可见,退出FindNumsWithSum后,局部变量data销毁,num1,num2保存的地址又变回了原来的0x602010 0x602030