【闲来刷 leetcode】 Two Sum | leetcode OJ

Two Sum (点击可以链接到leetcode OJ问题描述和代码提交页面)
<问题描述>
	给定一个整形数组,需要从数组中找出两个整数,使得它们之和等于另外一个给定的整数
	下面给出的twoSum函数应该返回需要找到的这两个整数对应的索引值,当然,这两个索引值index1 和 index2必须满足这样两个特性,index1必须小于index2 和 这两个索引都不是基于0的下标索引 (注:返回的索引是 在数组的下标索引值 + 1)
	你可以假定对应的每一个输入有且仅有一个答案
	输入 : numbers = {2, 7, 11, 15}, target = 9  (注 : 不要被这个样例输入迷惑, 输入的数组元素不一定是有序的)
	输出 : index1 = 1, index 2 = 2
<问题分析>
	1. 双层循环,O(n * n) 的时间复杂度,很清楚的思路,但是数组足够大的时候,太慢了吧,过不了 large input 的。
	2. 如果数组是有序的,当然有比较好的 O(n)复杂度的算法,首尾同时遍历。
	3. 如果直接在原始数组上排序,必然最后得到的索引是错误的(当然你要坑我的说,如果原始数组已经是非降序的,那另说)。因此我们另定义一个和原始数组一样的数组,在这个新数组上排序,然后查找,然后根据查找到的元素去元素数组上定位索引,为啥?上面说‘你可以假定对应的每一个输入,有且只有一个答案’,不存在两个答案。但是也要注意,可能这两个元素相同,如目标值是 10,要查找的两个元素是5, 5.
<Code>
class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        vector<int> answer(2, 0);
        vector<int> temp = numbers;
        
        sort(temp.begin(), temp.end());
        int length = temp.size();
        int left = 0;
        int right = length - 1;
        /*
         * 下面的while循环,只循环一次n数组
         * 因为temp数组是有序的,首尾同时遍历,
         * 如果之和sum < target, 那么我们只能通过将左指示器向右移一位来增大 sum
         * 如果之和sum > target, 那么我们通过右指示器向左移一位来减小 sum
         * 必定有一个sum == target,此时break,退出循环
         */
        while (left < right)
        {
            int sum = temp[left] + temp[right];
            if (sum == target)
            {
                break;
            }
            else if (sum < target)
            {
                ++ left;
            }
            else
            {
                -- right;
            }
        }
        
       /*
        * 略加注意如 目标值是 10,要查找的两个元素是5, 5 这样的情况,两个元素值相同
        *
        */
        for (int i = 0; i < length; ++ i)
        {
            if (temp[left] == numbers[i] || temp[right] == numbers[i])
            {
                if (answer[0] == 0)
                {
                    answer[0] = i + 1;
                }
                else
                {
                    answer[1] = i + 1;
                    break;
                }
            }
        }

        return answer;
    }
};


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值