【leetcode】two sum --medium

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

采用二分查找的方法求解,但是超时了。最差情况下的复杂度为O(n^2)

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        int last_first_position=0;
        return twoSum(nums,target,last_first_position);
    }
    vector<int> twoSum(vector<int>& nums, int target,int &last_first_position) {
        int n=nums.size();
        int n_half=n/2;
        if(n_half>=2)
        {
            vector<int> nums_lhalf;
            nums_lhalf.insert(nums_lhalf.end(),nums.begin(),nums.begin()+n_half);
            indexs=twoSum(nums_lhalf,target,last_first_position);  //如果是选择左边的数组子集进行递归,那么last_first_position值不变
            nums_lhalf.clear();
            if(!indexs.empty())    //如果不加上这个判定,那么会找到所有符合条件的indexs
                return indexs;
        }
        if(n-n_half>=2)
        {
            last_first_position+=n_half;   //否则首地址就要加上一半
            vector<int> nums_rhalf;
            nums_rhalf.insert(nums_rhalf.end(),nums.begin()+n_half,nums.end());
            indexs=twoSum(nums_rhalf,target,last_first_position);
            if(!indexs.empty())     //如果已经在左子集找到了符合条件的位置,就直接返回值。
                return indexs;
            nums_rhalf.clear();
            last_first_position-=n_half;   //说明不是在右子数组中找到的,需要还原该值
        }
        //只有在n_half>=2时才进行递归,因而在下面的循环中n_half一定是大于等于1的
        for(int i=0;i<n_half;i++)    //如果这个数组的两个子集都没有找到合适的indexs才在当前数组中去寻找
            for(int j=n_half;j<n;j++)
            {
                if(nums[j]==target-nums[i])
                {
                    indexs.push_back(i+last_first_position+1);   //如果这样写,输出的就只是ij的值,应该要输出确定的位置
                    indexs.push_back(j+last_first_position+1);
                    break;    
                }
            }
            return indexs;    
    }
private:vector<int> indexs;
};  

用指针代替向量,但是还是超时了。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        int* first_position,* last_position;
        int position=0;
        first_position=&nums[0];
        last_position=&nums[0]+nums.size();
        return twoSum(nums,target,first_position,last_position,position);
    }
    vector<int> twoSum(vector<int> nums, int target,int* &first_position,int* &last_position,int &position) {
        int n=last_position-first_position;
        int n_half=n/2;
        if(n_half>=2)
        {
            last_position-=n-n_half;
            indexs=twoSum(nums,target,first_position,last_position,position);    
            if(!indexs.empty())    //如果不加上这个判定,那么会找到所有符合条件的indexs
                return indexs;
            last_position+=n-n_half;
        }
        if(n-n_half>=2)
        {
            position+=n_half;
            first_position+=n_half;
            indexs=twoSum(nums,target,first_position,last_position,position);
            if(!indexs.empty())    //如果不加上这个判定,那么会找到所有符合条件的indexs
                return indexs;
            first_position-=n_half;
            position-=n_half;
        }
        //只有在n_half>=2时才进行递归,因而在下面的循环中n_half一定是大于等于1的
        for(int i=0;i<n_half;i++)    //如果这个数组的两个子集都没有找到合适的indexs才在当前数组中去寻找
            for(int j=n_half;j<n;j++)
            {
                if(*(first_position+j)==target-(*(first_position+i)))
                    {
                        indexs.push_back(i+position+1);   
                        indexs.push_back(j+position+1);
                        break;
                }
            }
            return indexs;
    }
    private:vector<int> indexs;
};

void main()
{
    Solution s;
    vector<int> nums;
    nums.push_back(3);
    nums.push_back(2);
    nums.push_back(4);
    nums.push_back(7);
    nums.push_back(8);
    cout<<s.twoSum(nums,11)[0]<<' '<<s.twoSum(nums,11)[1];
}

 换种思路:先进行快速排序。然后设置low和high,如果nums[low]+nums[high]<target,则low++;

如果nums[low]+nums[high]>target,则high--。依然超时。

快排+二分查找,依然超时。

//快速排序算法实现
//并且把原来的位置记录下来
#include<iostream>
using namespace std;
#include<vector>

class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target)
        {
            vector<int> indexs;
            nums.insert(nums.begin(),0);      //加入0号位
            vector<int> position;                 //初始化position数组.
            for(int i=0;i<=nums.size()-1;i++)
            {
                position.push_back(i);
            }
            QSort(nums,1,nums.size()-1,position);   //全排
            //开始找2个数的和等于target的值
            int low=1;
            int high=nums.size()-1;
            while(low<high)
            {
                if(nums[low]+nums[high]<target)
                    low++;
                else if(nums[low]+nums[high]>target)
                    high--;
                else
                    break;
            }
            //开始输出找到的位置
            if(position[low]<position[high])
            {
                indexs.push_back(position[low]);
                indexs.push_back(position[high]);
            }
            else
            {
                indexs.push_back(position[high]);
                indexs.push_back(position[low]);
            }
            return indexs;
        }
private:
    int Partition(vector<int>& L,int low,int high,vector<int>& position)   
    {
        L[0]=L[low];    //L[0]号位置是没有用的,用来存储枢纽值
        position[0]=position[low];    //position[0]存储的是枢纽值在L中的位置
        while(low<high)
        {
            while(low<high&&L[high]>L[0]) --high;    //比哨兵位置大的值就不变,把high往前移
            L[low]=L[high];   //与哨兵相等的值也要往前移动
            position[low]=position[high];    
            while(low<high&&L[low]<=L[0]) ++low;     //比哨兵大的值才往后面移动,保证了所有小于等于哨兵的值都在哨兵的前面。
            L[high]=L[low];
            position[high]=position[low];
        }
        //到此为止,low一定是等于high的
        L[low]=L[0];   //再把L[0]处的值还原到L[low]
        position[low]=position[0];   //把枢纽位置在L中的位置放到position应该有的位置中
        return low;
    }
    void QSort(vector<int>& L,int low,int high,vector<int>& position)
    {
        if(low<high)
        {
            int pivotloc=Partition(L,low,high,position);
            QSort(L,low,pivotloc-1,position);
            QSort(L,pivotloc+1,high,position);
        }
    }
};

void main()
{
    Solution s;
    vector<int> nums;
    vector<int> indexs;
    nums.push_back(0);
    nums.push_back(4);
    nums.push_back(3);
    nums.push_back(0);
    indexs=s.twoSum(nums,0);
    cout<<indexs[0]<<' '<<indexs[1];
}

 二分查找:

    int search(vector<int> L,int target,int low,int high)     //二分查找,返回的是target所在的位置.如果没有找到,返回-1
    {
        if(low>high)
            return -1;
        int mid=low+(high-low)/2;
        if(target<L[mid])
            return search(L,target,low,mid-1);
        else if(target>L[mid])
            return search(L,target,mid+1,high);
        else
            return mid;
    }
原文地址:https://www.cnblogs.com/wy1290939507/p/4526230.html