主页 > IT业界  > 

解决“两数之和”问题:两种实现方法详解

解决“两数之和”问题:两种实现方法详解

目录

 

一、引言

二、暴力枚举法实现

2.1 代码实现

2.2 代码分析

2.3 时间与空间复杂度

三、排序 + 双指针法实现

3.1 代码实现

3.2 代码分析

3.3 时间与空间复杂度

四、总结


 

一、引言

 

在算法学习和编程面试中,“两数之和”是一个经典的问题。它不仅考察对基本数据结构和算法的理解,还能体现程序员解决问题的思路和代码实现能力。给定一个整数数组  nums  和一个整数目标值  target ,要求在数组中找出和为目标值的那两个整数,并返回它们的数组下标,同时规定每种输入只会对应一个答案,且不能使用两次相同的元素。

 

二、暴力枚举法实现

 

2.1 代码实现

 

c int* twoSum(int* nums, int numsSize, int target, int* returnSize) {     int *result = (int *)malloc(2 * sizeof(int));     *returnSize = 2;     for (int i = 0; i < numsSize - 1; i++) {         for (int j = i + 1; j < numsSize; j++) {             if (nums[i] + nums[j] == target) {                 result[0] = i;                 result[1] = j;                 return result;             }         }     }     return NULL; } 2.2 代码分析

 

这段代码采用了暴力枚举的方法。外层循环遍历数组中的每个元素,对于每个元素  nums[i] ,内层循环从  i + 1  开始遍历后续的元素  nums[j] ,检查  nums[i] + nums[j]  是否等于目标值  target 。如果找到符合条件的两个数,就将它们的下标存入动态分配的数组  result  中并返回。如果遍历完整个数组都没有找到,则返回  NULL 。

 

2.3 时间与空间复杂度

 

- 时间复杂度:由于使用了两层嵌套循环,时间复杂度为 O(n^2),其中 n 是数组的长度。

 

- 空间复杂度:只使用了常数级别的额外空间,空间复杂度为 O(1)。

 

三、排序 + 双指针法实现

 

3.1 代码实现

 

c typedef struct {     int val;     int index; } NumIndex; // 比较函数,用于qsort排序 int cmp(const void *a, const void *b) {     NumIndex *num1 = (NumIndex *)a;     NumIndex *num2 = (NumIndex *)b;     return num1->val - num2->val; } int* twoSum(int* nums, int numsSize, int target, int* returnSize) {     // 创建结构体数组,并初始化     NumIndex *numIndexArr = (NumIndex *)malloc(numsSize * sizeof(NumIndex));     for (int i = 0; i < numsSize; i++) {         numIndexArr[i].val = nums[i];         numIndexArr[i].index = i;     }     // 对结构体数组进行排序     qsort(numIndexArr, numsSize, sizeof(NumIndex), cmp);     int left = 0, right = numsSize - 1;     int *result = (int *)malloc(2 * sizeof(int));     *returnSize = 2;     while (left < right) {         int sum = numIndexArr[left].val + numIndexArr[right].val;         if (sum == target) {             result[0] = numIndexArr[left].index;             result[1] = numIndexArr[right].index;             free(numIndexArr);             numIndexArr=NULL;             return result;         } else if (sum < target) {             left++;         } else {             right--;         }     }     free(numIndexArr);     free(result);     numIndexArr=NULL;     result=NULL;     return NULL; } 3.2 代码分析

 

首先定义了一个结构体  NumIndex ,用于存储数组元素的值和其对应的下标。然后创建一个结构体数组  numIndexArr  并初始化,将原数组的元素值和下标存入其中。接着使用  qsort  函数对结构体数组按照元素值进行排序。

 

排序完成后,使用双指针法,左指针  left  指向数组开头,右指针  right  指向数组末尾。通过计算  numIndexArr[left].val + numIndexArr[right].val  的和与目标值  target  比较:


- 如果和等于目标值,说明找到了符合条件的两个数,将它们在原数组中的下标存入  result  数组并返回,同时释放动态分配的  numIndexArr  内存。

 

- 如果和小于目标值,将左指针  left  右移,增大和的值。

 

- 如果和大于目标值,将右指针  right  左移,减小和的值。

如果遍历完整个数组都没有找到符合条件的数,释放所有动态分配的内存并返回  NULL 。


3.3 时间与空间复杂度

 

- 时间复杂度:排序的时间复杂度为 O(n log n),双指针遍历数组的时间复杂度为 O(n),总体时间复杂度为 O(n log n),比暴力枚举法更优。

 

- 空间复杂度:使用了一个额外的结构体数组来存储元素值和下标,空间复杂度为 O(n)。

 

四、总结

 

本文介绍了两种解决“两数之和”问题的方法。暴力枚举法简单直接,但时间复杂度较高;排序 + 双指针法通过对数组进行预处理和双指针的巧妙运用,降低了时间复杂度,提高了算法效率。在实际应用中,可以根据具体的需求和数据规模选择合适的方法。希望通过这篇博客,读者能对该问题有更深入的理解,并且在遇到类似问题时能够灵活运用这些思路和方法。

 

标签:

解决“两数之和”问题:两种实现方法详解由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“解决“两数之和”问题:两种实现方法详解