当前位置: 首页 > article >正文

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

目录

 

一、引言

二、暴力枚举法实现

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)。

 

四、总结

 

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

 


http://www.kler.cn/a/567053.html

相关文章:

  • 双臂机器人的动力学建模
  • 浅入浅出Selenium DevTools
  • Oracle日常管理(8)——DB日常管理(2)
  • 正大杯攻略|量表类问卷数据分析基本步骤
  • Html5学习教程,从入门到精通,HTML 5 图像语法知识点语法知识点及案例代码(9)
  • #深入了解DNS3和VCTK语音数据集
  • 模拟器游戏多开为什么需要单窗口单IP
  • MES:开启生产制造优秀管理新时代
  • 博客系统完整开发流程
  • LeetCode 每日一题 2025/2/24-2025/3/2
  • 人工智能之数学基础:线性代数中矩阵的运算
  • 国产RISCV64 也能跑AI
  • FFmpeg-chapter2-C++中的线程
  • 基于 Spring Boot 的 +Vue“宠物咖啡馆平台” 系统的设计与实现
  • Pwntools 的详细介绍、安装指南、配置说明
  • 零信任架构
  • 练习题:61
  • C++杂记——尾递归
  • ‌Tomcat 8.0.12安装流程
  • 【Android】Android Studio 中文乱码问题解决方案