今天注册了大名鼎鼎的LeetCode,做了一道最简单的算法题目:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

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

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

UPDATE (2016/2/13):

The return format had been changed to zero-based indices. Please read the above updated description carefully.

Subscribe to see which companies asked this question

虽然题目很简单,但是在做的过程中暴露的问题也是比较多的。

1.多年不碰英语,题目看不懂,很多细节没有理解(例如给定的序列中的数字是不是可以重复、以及序列的长度等)

2.由于没有做过类似的网上直接运行提交的题目,所以一时间不会搞

3.用惯了VS的只能提示,导致直接写代码的时候字母的大小写经常错误

4.可能导致程序崩溃的条件不加,例如这个题目,明显在输入的数组的长度小于2时候可以直接返回

我的程序:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        ];
        )
        {
            return temp;
        }
        ;i<=nums.Length - ;i++){
            ;j<=nums.Length - ;j++){
                if((nums[i] + nums[j] == target)){
                    temp[] = i;
                    temp[] = j;
                    return temp;
                }
            }
        }
        return temp;
    }
}

做完提交后会有一个性能分析和排名:

通过上面可以看到我的计算方法的效率,说明有60%多的算法比我这个效率要高,所以可以看看人家是怎么做的:

查看算法的讲解,有一种方法是采用了哈希表的方式,我上面的方式采用的是暴力搜索的方式,时间复杂度O(n​2​​),而采用哈希的方式是O(n)

Approach #2 (Two-pass Hash Table) [Accepted]

To improve our run time complexity, we need a more efficient way to check if the complement exists in the array. If the complement exists, we need to look up its index. What is the best way to maintain a mapping of each element in the array to its index? A hash table.

We reduce the look up time from O(n)O(n) to O(1)O(1) by trading space for speed. A hash table is built exactly for this purpose, it supports fast look up in nearconstant time. I say "near" because if a collision occurred, a look up could degenerate to O(n)O(n) time. But look up in hash table should be amortized O(1)O(1) time as long as the hash function was chosen carefully.

A simple implementation uses two iterations. In the first iteration, we add each element's value and its index to the table. Then, in the second iteration we check if each element's complement (target - nums[i]target−nums[i]) exists in the table. Beware that the complement must not be nums[i]nums[i] itself!

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

Complexity Analysis:

  • Time complexity : O(n)O(n). We traverse the list containing nn elements exactly twice. Since the hash table reduces the look up time to O(1)O(1), the time complexity is O(n)O(n).

  • Space complexity : O(n)O(n). The extra space required depends on the number of items stored in the hash table, which stores exactly nn elements.

思路有了,用C#去改写

        public int[] TwoSum(int[] nums, int target)
        {
            if (nums.Length < 2)
            {
                throw new Exception();
            }
            Dictionary<int, int> dict = new Dictionary<int, int>();
            for (int i = 0; i <= nums.Length - 1; i++)
            {
                dict.Add(i, nums[i]);
            }
            for (int i = 0; i <= nums.Length - 1; i++)
            {
                int temp = target - nums[i];

                if (dict.ContainsValue(temp) && dict.FirstOrDefault(q => q.Value == temp).Key != i)
                {
                    return new int[] { dict.FirstOrDefault(q => q.Value == temp).Key, i };
                }
            }
            throw new Exception();
        }

但是在提交的时候出现了问题:

超时了!!!!

和大神们讨论了一下也没发现什么问题。

还有一种是这个变种:

Approach #3 (One-pass Hash Table) [Accepted]

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[] { map.get(complement), i };
        }
        map.put(nums[i], i);
    }
    throw new IllegalArgumentException("No two sum solution");
}

就是把上面的两次循环,变成了一次循环,把先构建哈希表变成了后构建,每次循环时候去看是否存在。

偶然发现有人这么写的,于是就扒下来看了一下:

public int[] TwoSum(int[] nums, int target)
{
    int numsLength = nums.Length;
)
    {
         return nums;
    }
    ];
    var numsInDictionary = new Dictionary<int, int>();

    ; i < numsLength; i++)
    {
        if (numsInDictionary.ContainsKey(target - nums[i]))
        {
             result[] = i;
             result[] = numsInDictionary[target - nums[i]];
             break;
        }
        if (!numsInDictionary.ContainsKey(nums[i]))
        {
             numsInDictionary.Add(nums[i], i);
        }
    }
    return result;
}

LeetCode初体验—twoSum的更多相关文章

  1. [leetcode]leetcode初体验

    这几天把之前的设计模式回顾了一遍,整理了一点以前的项目.同学说,打算刷leetcode题目,也勾起了我的兴趣,索性也刷一些题目,再提高一些内功.刚开始进去,leetcode随机分配的题目,直接也就做了 ...

  2. .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验

    不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...

  3. Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验

    Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...

  4. Spring之初体验

                                     Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...

  5. Xamarin.iOS开发初体验

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0

  6. 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...

  7. 【Knockout.js 学习体验之旅】(1)ko初体验

    前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...

  8. 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验

    在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...

  9. 百度EChart3初体验

    由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...

随机推荐

  1. openstack api

    1,Identity service generates authentication tokens that permit access to the openstack service REST ...

  2. Spring基础知识汇总 Java开发必看

    Spring简介 Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版.Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅 ...

  3. ubuntu无法进入和引导顺序问题解决

    今天上班过来发现ubuntu无法进入,因为里面有N多资料没有备份,当时很是捉急.不过后来都解决了: 背景: easyBCD安装ubuntu14.07和windows7双系统.基本上这一年多一直用ubu ...

  4. Java正则表达式--网页爬虫

    网页爬虫:其实就一个程序用于在互联网中获取符合指定规则的数据 爬取邮箱地址,爬取的源不同,本地爬取或者是网络爬取 (1)爬取本地数据: public static List<String> ...

  5. nyoj 17 单调递增最长子序列

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4   输入 ...

  6. 转载StringBuilder说明

    动态串StringBuilder 利用System.Text.StringBuilder类实现动态字符串,动态的含义是指在修改字符串时,系统不需要创建新的对象,不会重复开辟新的内存空间,而是直接在原来 ...

  7. 转载总结一些关于Google chart api的知识

    <script type="text/javascript">      google.setOnLoadCallback(drawChartLine);      f ...

  8. 【Away3D代码解读】其它一些的记录(持续更新)

    查看当前正在使用的AGAL代码可以在程序开始时添加下面的代码,AGAL代码会被trace出来: Debug.active = true; 具体的输出是在MaterialPassBase类的update ...

  9. javascript深入理解闭包(转)

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

  10. 创建、显示和删除保存的用户名和密码(cmdkey)

    创建,显示和删除保存的用户名和密码: cmdkey.exe /add:targetname /user:username /pass:password