算法题1两数之和

问题:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

解法一:暴力解法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int i,j;
        for(i=0;i<nums.size()-1;i++)
        {
            for(j=i+1;j<nums.size();j++)
            {
                if(nums[i]+nums[j]==target)
                {
                   return {i,j};
                }
            }
        }
        return {i,j};
    };
};
// 定义一个函数twoSum,它接受一个整数指针nums(指向整数数组的起始位置),一个整数numsSize(表示数组的大小),  
// 以及一个整数target(表示目标和),并返回一个整数指针result,该指针指向一个包含两个整数的数组,  
// 这两个整数是数组中相加等于target的两个数的索引。  
int* twoSum(int* nums, int numsSize, int target) {  
    int i,j; // 定义两个循环变量i和j,用于遍历数组。  
    int *result=NULL; // 定义一个整数指针result,并初始化为NULL。这个指针将用于存储找到的索引对。  
  
    // 外层循环,从数组的第一个元素开始遍历到倒数第二个元素。  
    for(i=0;i<numsSize-1;i++) {  
        // 内层循环,从外层循环当前元素的下一个元素开始遍历到数组的最后一个元素。  
        for(j=i+1;j<numsSize;j++) {  
            // 判断当前两个元素之和是否等于目标值target。  
            if(nums[i]+nums[j]==target) {  
                // 如果等于target,则动态分配内存来存储两个索引。  
                result=(int*)malloc(sizeof(int)*2);  
                // 将找到的索引赋值给result指向的数组。  
                result[0]=i;  
                result[1]=j;  
                // 返回结果指针。  
                return result;  
            }  
        }  
    }  
    // 如果没有找到满足条件的索引对,则返回NULL。  
    return result;  
}

malloc给result分配了两个int类型大小的空间,可知result是一个数组。

最容易理解,但是他的时间复杂为O(n2),因为这是两个for循环。

解法二:使用哈希表

class Solution {  
public:  
    // 定义一个函数twoSum,接受一个整数向量nums和一个整数target,返回一个整数向量  
    vector<int> twoSum(vector<int>& nums, int target) {  
        // 创建一个哈希表a,用于存储数组元素和它们的索引  
        map<int,int> a; // 建立hash表存放数组元素  
          
        // 初始化一个大小为2的整数向量b,用于存放结果,初始值设为-1  
        vector<int> b(2,-1); // 存放结果  
          
        // 遍历数组nums,将数组元素和对应的索引插入到哈希表a中  
        for(int i=0;i<nums.size();i++)  
            a.insert(map<int,int>::value_type(nums[i],i));  
          
        // 再次遍历数组nums  
        for(int i=0;i<nums.size();i++) {  
            // 判断是否存在target - nums[i]这个键,并且该键对应的值不等于当前索引i  
            // 这样做是为了确保找到的两个数不是同一个数  
            if(a.count(target-nums[i])>0 && (a[target-nums[i]]!=i))  
                // 如果找到,则将当前索引i和target - nums[i]对应的索引存入结果向量b中  
                // 并跳出循环  
            {  
                b[0]=i;  
                b[1]=a[target-nums[i]];  
                break;  
            }  
        }  
          
        // 返回结果向量b  
        return b;  
    };  
};
class Solution {  
public:  
    vector<int> twoSum(vector<int>& nums, int target) {  
        map<int,int> a;  
        vector<int> b(2,-1);  
        for(int i=0;i<nums.size();i++) {  
            if(a.count(target-nums[i])>0) {  
                b[0]=a[target-nums[i]]; // 正确的应该是这个数的索引  
                b[1]=i; // 当前数的索引  
                break;  
            }  
            a[nums[i]]=i;  
        }  
        return b;  
    };  
};

不同于数组,哈希表找数的时间复杂度为O(1),所以这里的时间复杂度应为O(n)

上一篇:web学习笔记(四十五)Node.js


下一篇:Linux---命令行参数