给定一个自增序列数组,总数组中找出两个元素等于目标值,并输出元素的下标。这个题右很多解法,通过hash可以将时间复杂度降到O(n),但是需要额外开辟空间,那么原地算法非常适合解决此题,及保障时间复杂度,亦可保障空间复杂度的最优。
1、算法思路
cpp
/**
* 展示数组
*/
void show_arr(uint32* head,int len)
{
if(head == NULL){
perror("arr is not init");
exit(0);
}
printf("----------------\n");
int i = 0;
for(i;i<len;i++)
{
printf("%d\t",head[i]);
}
printf("\n");
}
/**
* 求两数之和 递增数列
* @param head 数组首地址
* @param len 数字长度
* @param sum 目标数
*/
void two_sum(int* head,int len,int sum)
{
int left = 0 , right = len -1 ;
int flag = 0;
while (left < right)
{
/// 两数之和
int temp = head[left] + head[right];
int diff = temp - sum;
if(diff > 0)
{
/// 差值大于0,说明当前temp大于目标值,需要将右指针左移,减小temp,使得temp靠近目标值
right --;
}
else if(diff < 0 )
{
/// 差值小于0,说明当前temp小于于目标值,需要将左指针右移,增大temp,使得temp靠近目标值
left ++;
}
else
{
flag = 1;
/// temp命中目标值
printf("left=%d,right=%d,temp=%d\n",left,right,temp);
left ++;
right --;
}
}
if(flag ==0)
{
printf("%s\n"," The arr can not find two number that sum equal target value ");
}
}
2、测试算法
cpp
int arr[] = { 8 , 12 , 15, 23 , 27 , 34 , 39 ,41 ,46, 55, 67, 76, 83 };
int* head = &arr[0];
int len = sizeof(arr)/sizeof(int);
two_sum(head,len,70);
下标2对应的是15,下标9对应的是55,两数之和正好是70.