zoukankan      html  css  js  c++  java
  • leetcode 1 Two Sum(查找)

    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

    solution:暴力算法很显然是O(n2)会超时。

    那么我的做法是把数组排序后二分查找。这样是O(n*lgn)。这里注意一个细节是类内的cmp比较函数要定义成静态成员函数,不然sort调用时会报错:invalid use of non-static member function。因为非静态成员函数是依赖于具体对象的,而std::sort这类函数是全局的,因此无法再sort中调用非静态成员函数。静态成员函数或者全局函数是不依赖于具体对象的, 可以独立访问,无须创建任何对象实例就可以访问。同时静态成员函数不可以调用类的非静态成员。

    还有discuss里有更好的O(n)算法,就是hash的思想,利用unordered_map这一无序map来使查找的时间接近常数。unordered_map和map的区别是它无序,所以在不需要排序时最好使用它,比map更快。

    class Solution {
    public:
        struct node{
            node(int i,int v):id(i),val(v){}
            int id,val;
        };
        static bool cmp(node a,node b){
            return a.val<b.val;
        }
        vector<int> twoSum(vector<int>& nums, int target) {
            vector<node>vt;
            vector<int>ans;
            vector<int>::iterator it;
            int a1=0,a2=1;
            for(it=nums.begin();it!=nums.end();it++){
                vt.push_back(node(++a1,*it));
            }
            sort(vt.begin(),vt.end(),cmp);
            a1=0;
            for(it=nums.begin();it!=nums.end();it++){
                int t=*it;
                a1++;
                a2=lower_bound(vt.begin(),vt.end(),node(0,target-t),cmp)-vt.begin();
                int a3=upper_bound(vt.begin(),vt.end(),node(0,target-t),cmp)-vt.begin();
                if(a2<vt.size()&&a2==a3&&vt[a2].val==target-t&&vt[a2].id>a1){
                    a2=vt[a2].id;
                    //printf("index1=%d, index2=%d
    ",a1,a2);
                    ans.push_back(a1);
                    ans.push_back(a2);
                    return ans;
                }
                else if(a2<vt.size()&&vt[a2].val==target-t&&a2<a3){/*这个处理很有必要,不然[0,4,3,0]和target=0
                这组数据会WA,二分时要注意考虑有几个相等的情况*/
                    for(int i=a2;i<a3;i++){
                        if(vt[i].id>a1){
                            ans.push_back(a1);
                            ans.push_back(vt[i].id);
                            return ans;
                        }
                    }
                }
                
            }
            return ans;
        }
    };
    my answer
    vector<int> twoSum(vector<int> &numbers, int target)
    {
        //Key is the number and value is its index in the vector.
        unordered_map<int, int> hash;
        vector<int> result;
        for (int i = 0; i < numbers.size(); i++) {
            int numberToFind = target - numbers[i];
    
                //if numberToFind is found in map, return them
            if (hash.find(numberToFind) != hash.end()) {
                        //+1 because indices are NOT zero based
                result.push_back(hash[numberToFind] + 1);
                result.push_back(i + 1);            
                return result;
            }
    
                //number was not found. Put it in the map.
            hash[numbers[i]] = i;
        }
        return result;
    }
    better answer in discuss
  • 相关阅读:
    [C#]LDAP验证用户名和密码
    如何为 Go 设计一个通用的日志包
    使用 Go 的 struct tag 来解析版本号字符串
    Referrer Policy 介绍
    《计算机操作系统》MOOC笔记1-计算机系统概论
    C语言的Bit fields
    【转】gcc编译优化---likely()与unlikely()函数的意义
    三向切分的快速排序
    Codeforces Round #334 (Div. 2) C. Alternative Thinking
    基于相邻元素交换的排序算法的下界
  • 原文地址:https://www.cnblogs.com/zywscq/p/4887771.html
Copyright © 2011-2022 走看看