Question 1 of leetcode, two sum

Source: Internet
Author: User

When I got up and went to the data center this morning, I was still thinking about it. I always felt unreliable without algorithm questions. Doing questions always makes you feel that you are actually doing learning ....


This is also an obsessive-compulsive disorder.

Let's start to do the leetcode from today. Because I haven't done it for a long time, I still read the answers and ideas of other people.


In general, the first question is water ....



Restore question

Two sum

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

The function twosum shocould 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 wowould have exactly one solution.

Input:Numbers = {2, 7, 11, 15}, target = 9
Output:Index1 = 1, index2 = 2

An integer array and a target value are provided to find the subscript of the two elements in the array and the elements of the target value. The output is index1 and index2, output in ascending order. It is assumed that each array exactly contains a solution, even if each given array has only one matching result.

Answer

First, this type of question generally needs to be sorted for speed and convenience.

Of course, it can be done without sorting, but the complexity seems a bit unreasonable.

Although the given array is not given in order, we need to know that in the world of this algorithm, everything is simple.

Ordered value. Unfortunately, my life is still a little messy ....

However, because the element subscript of the original array is returned at the end, we must make a copy in the space of the original array ....

Then I create a copy. First, assume that the copy is from small to large. As for how to create a copy, I think of a method:

Select the cursor between the left and right, and take the sum of the two. If the sum is equal to the target value, the element represented by the cursor is located in the original array and the subscript is saved in the index. To be returned.

If the sum is greater than the target value, move the right subscript to the left;

If the sum is smaller than the target value, move the left subscript to the right.

Until the left and right are equal.

The implementation code is as follows:

/*************************************** * *********************************> File Name: twosum. CPP> author: suool> mail: [email protected]> created time: ******************************** **************************************** /class solution {public: vector <int> twosum (vector <int> & numbers, int target) {// note: the solution object is instantiated only once and is reused by each test case. vector <int> num = numbers; STD: Sort (Num. begin (), num. end (); int length = numbers. size (); int left = 0; int right = length-1; int sum = 0; vector <int> index; while (left <right) {sum = num [left] + num [right]; If (sum = target) {// find the index from the old array for (INT I = 0; I <length; ++ I) {If (numbers [I] = num [left]) {index. push_back (I + 1);} else if (numbers [I] = num [right]) {index. push_back (I + 1);} If (index. size () = 2) {break;} else if (sum> Target) {-- right;} else {++ left ;}} return Index ;}};

Python code: 

#!/usr/bin/env python# coding=utf-8class Solution:    # @return a tuple, (index1, index2)    def twoSum(self, num, target):             numbers = sorted(num)        length = len(num)        left = 0        right = length - 1        index = []        while left < right:             sums = numbers[left] + numbers[right]            if sums == target:                for i in range(length):                    if num[i] == numbers[left]:                        index.append(i + 1)                    elif num[i] == numbers[right]:                        index.append(i + 1)                                        if len(index) == 2:                        break                break            elif sums > target:                right -= 1            else:                left += 1        result = tuple(index)        return result
The following is a similar solution on the network, using the latest C ++ 11 standard. Worship.

/*************************************** * *********************************> File Name: twosum_c11.cpp> author: suool> mail: [email protected]> created time: ******************************** **************************************** /class solution {public: typedef pair <int, size_t> valoffset_pair_t; vector <int> twosum (vector <int> & numbers, int target) {vector <valoffset_pair _ T> new_array; // preallocate the memory for faster push_back new_array.reserve (numbers. size (); // generate the new array int Index = 0; For (Auto I: Numbers) new_array.push_back (valoffset_pair_t (I, ++ index); // note: here the index is already increased, so // The new indices are not zero based // sort it! Sort (begin (new_array), end (new_array), [&] (const valoffset_pair_t & V1, const valoffset_pair_t & V2)-> bool {return v1.first <v2.first ;}); // now find the right pair using two pointers auto p_left = begin (new_array); Auto p_right = end (new_array); p_right --; // Make It locate at the last position int sum = p_left-> first + p_right-> first; // It is guaranteed to have one exact solution while (sum! = Target) {sum = p_left-> first + p_right-> first; If (sum> Target) p_right --; else if (sum <target) p_left ++; else break ;} return vector <int> ({min (p_left-> second, p_right-> second), max (p_left-> second, p_right-> second )});}};

At the same time, we can see that only the hashmap method of O (n) is used. The idea is to loop once. If the value of the current array index location is not in hashtable, add it if it is not, key is a numerical value, and value is its index value. In this case, the key is obtained and recorded as N (at this time, N must be smaller than the cyclic variable I ), next, search for the value (Target-current value) in hashtable, and take advantage of the constant element time in hashtable. If it is found, it will end. Note that, if there are repeated values in the array, the second occurrence will not be added to hashtable, such as 3, 4, 3, 6; target = 6. When the loop is to the second 3, you can also get the correct result.

The Code is as follows:

class Solution {public:    vector<int> twoSum(vector<int> &numbers, int target) {        int i, sum;        vector<int> results;        map<int, int> hmap;        for(i=0; i<numbers.size(); i++){// if the number doesn`t existed in the hashtable            if(!hmap.count(numbers[i]))     {// insert the number and its index                hmap.insert(pair<int, int>(numbers[i], i));            }// find the number which equal to target - numbers[i]            if(hmap.count(target-numbers[i])){                int n=hmap[target-numbers[i]];                if(n<i){                    results.push_back(n+1);                    results.push_back(i+1);                    //cout<<n+1<<", "<<i+1<<endl;                    return results;                }            }        }        return results;    }};

Python:

class Solution:# @return a tuple, (index1, index2)def twoSum(self, num, target):length = len(num)index = []hash_tab = {}for i in range(length):if( not hash_tab.has_key(num[i])) :pair = {num[i] : i}hash_tab.update(pair)if( hash_tab.has_key(target - num[i] )) :n = hash_tab[target-num[i]]if n< i :index.append(n + 1)index.append(i + 1)result = tuple(index)return resultreturn result

The first thought of summary is the two-layer Traversal method, but obviously the time complexity is too high, which is O (n ^ 2) and does not meet the requirements. so we should think about how to reduce the complexity. First, we should try to convert the comparison one by one into direct search, that is, first calculate the difference between the target and the current element, and then look for the difference in the sequence, in this way, the problem is simplified first, and the search process can first sort the sequence quickly, and then perform binary search, so that the overall complexity is reduced to O (N * logn; the fastest way to search is to use a map container to store the index of each element. In this way, obtaining the index of a specific element takes only constant time, which is faster. You only need to traverse the sequence at most once, add the Element and Its Index to the map and search for the corresponding difference value during the traversal process. If the difference value is found, the traversal is completed. In this way, the time complexity is O (n) at most ), it's amazing!
In short, this is the first leetcode question I have made. I feel that this question is more rigorous than other OJ ones. For example, this question has strict execution time requirements and O (N ^ 2) cannot be used, you can give yourself reasons to optimize the program. Continue to cheer!
Submission record:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.