两数之和

简介:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

本人默认的是数组中存在重复元素,即需要在数组nums找到num[i] + num[j] = target;所以我的基本思路如下:
(1)用一个map(nums_map)存储原生的数组,key值是数组的下标i,value值是对应下标i的value;
(2)用上一篇文章的归并排序对数组nums进行从小到大的排序;
(3)依次遍历nums的元素i(nums[i]),然后用二分法查找 num[j],满足num[i] + num[j] = target则记录nums[i]和 num[j]于数组target_num中;
(4)通过nums_map依次查看target_num中的元素的下标,找到一个,则删除nums_map中有关的记录;

奉上代码如下:

class Solution {
public:
    void merge(std::vector<int>& input, int low, int mid, int high) {
        if ( input.size() == 0 || low >= high || mid > high || low > mid) {
            return ;
        }
        std::vector<int> temp_input(input);
    
        int first = low;
        int last = mid+1;

        for (int j = low; j <= high; j++) {
            if (first > mid) {
                input[j] = temp_input[last++];
            }
            else if (last > high) {
                input[j] = temp_input[first++];
            }
            else {
                input[j] = (temp_input[first] < temp_input[last]) ? temp_input[first++] : temp_input[last++];
            }
        }
    }

    void sort(std::vector<int>& input, int low, int high) {
        if (input.size() == 0 || low >= high) {
            return ;
        }
        int mid = low + (high - low) / 2;
        sort(input, low, mid);
        sort(input, mid + 1, high);
        merge(input, low, mid, high);
    }
    int binarySearch(vector<int>& nums, int right_index, int target)
    {
       
          int size = nums.size();
        int last_index = size -1;
        int low_bound = right_index;
        int high_bound = last_index;
        if (right_index >= last_index)
        {
            return -1;
        }
        int mid_index = right_index + (last_index - right_index + 1)/2;
        int right_value = nums[right_index];
        int mid_value = nums[mid_index];

        if (right_value > mid_value)
        {
            return -1;
        }
        while (mid_index > low_bound && mid_index < high_bound)
        {
            if  (target == (right_value + nums[mid_index]))
            {
                return mid_index;
            }
            else if (target > (right_value + nums[mid_index]))
            {

                low_bound = mid_index;
                mid_index = mid_index + (high_bound - mid_index + 1)/2;
            }
            else
            {
                high_bound = mid_index;
                mid_index = mid_index - (mid_index- low_bound + 1)/2;
            }

        }
        if  (target == (right_value + nums[mid_index]) && mid_index > right_index && mid_index <= last_index)
        {
            return mid_index;
        }
        return -1;
    }
    
    vector<int> twoSum(vector<int>& nums, int target) {
              //1.首先对数组进行排序
        vector<int> target_index;
        vector<int> target_num;
        int size = nums.size();

        map<int, int> nums_map;
        for (int i = 0; i < nums.size(); i++){
            nums_map[i] = nums[i];
        };

        sort(nums, 0, size -1);

        //2.再二分查找-a[i]
        int search_index = 0;
        for (int i = 0; i < size -1; i++)
        {
            if ((search_index = binarySearch(nums, i, target)) > 0 && search_index < size)
            {
                target_num.push_back(nums[i]);
                target_num.push_back(nums[search_index]);
            }

        }

        std::for_each(target_num.begin(), target_num.end(), [&](const int& num) {
            map<int, int>::iterator iter = nums_map.begin();
            for (; iter != nums_map.end(); iter++) {
                if (iter->second == num)
                {
                    target_index.push_back(iter->first);
                    nums_map.erase(iter->first);
                    break;
                }
            }
        });
        std::for_each(target_index.begin(), target_index.end(), [](const int& num){
            printf("%d", num);
        });

        return target_index;
    }
    
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值