LeetCode-1TwoSum(C#)
# 题目
1. Two Sum
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:
, , , ], target = , Because nums[] + nums[] = + = , , ].
UPDATE (2016/2/13):
The return format had been changed to zero-based indices. Please read the above updated description carefully.
# 思路
尝试暴力破解,(两个for循环)时间复杂度O(n^2),空间复杂度O(1),623ms。
// brute force: time O(n^2) space O(1) result: 632ms
public int[] TwoSum(int[] nums, int target)
{
; i < nums.Length; i++)
; j < nums.Length; j++)
if (nums[i] + nums[j] == target) return new int[] { i, j };
throw new Exception("no answer");
}
慢在哪里?和结果无关的计算太多。
举个例子,假设nums = {7, 2, 4, 6, 3},target = 8,即answer = {1, 3}。
暴力破解方法,对于1,计算了4 * 3 = 12次。真正有用的只有1次。计算的结果有些结果偏大,有些结果偏小,谷需要动态调整搜索的位置。
改进算法:
- 复制数组
- 复制的数组排序
- start指向复制的nums开头,表示answer较小元素在排序数组里的下标;end指向复制的nums结尾,表示answer较大元素在排序数组里的下标
- if start < end,表示target搜索未结束,转4,else 转8
- if start指针元素 + end指针元素 > target,说明start指针元素太小,start指针右移,返回3
- if start指针元素 + end指针元素 < target,说明end指针元素太大,end指针左移,返回3
- if start指针元素 + end指针元素 == target,说明找到满足target的answer,start指针右移,转8
- 取出start和end指针对应的元素,在nums中搜索并保存下标
- 输出下标组
技巧性搜索,(取最长的快速排序时间)时间复杂度O(nlgn),空间复杂度O(n),时间500ms。
// sort first, get left part and right part tricky, find left index and right index
// time: O(nlgn) space: O(n) 500ms
// reference: https://github.com/yangliguang yangliguang
public int[] TwoSum(int[] nums, int target)
{
int[] copy = new int[nums.Length];
Array.Copy(nums, copy, nums.Length);
Array.Sort(copy); // O(nlgn)
, end = copy.Length - , left = , right = ;
while (start < end) // O(n)
{
if (copy[start] + copy[end] == target)
{
left = copy[start];
right = copy[end];
break;
}
else if (copy[start] + copy[end] < target)
{
start++; // very tricky
}
else
{
end--; // very tricky
}
}
start = end = -;
; i < nums.Length; i++)
{
if (nums[i] == left)
{
start = i;
break;
}
}
; i >= ; i--)
{
if (nums[i] == right)
{
end = i;
break;
}
}
if (start > end) return new int[] { end, start };
else return new int[] { start, end };
}
还有另一种想法。
举个例子,举个例子,假设nums = {7, 2, 4, 6, 3},target = 8,即answer = {1, 3}。
我们随意挑出一个数,7,也就是说,我们只需要找到1,然而nums中没有1。再挑出6,nums中有2,满足条件,输出下标。
根据上述,可以设计算法:每次先取出一个数n,用target - n,查看与n配对的元素是否存在,存在就输出两个数的下标;不存在就
小细节:放入集合时,可以用Map连带放入下标,这样就不必再去搜索下标。
综合上述,我们选用Hashtable来完美的完成此题。
# 解决(Hashtable)
Hashtable,时间复杂度O(n),空间复杂度O(n),运行时间496ms。
// right hash: time O(n) (degenerate when collison occured) ususlly O(1) (insert and search) space: O(n) result: 496ms
public int[] TwoSum(int[] nums, int target)
{
];
System.Collections.Hashtable table = new System.Collections.Hashtable(nums.Length); // use empty constructor, result: 544 ms
; i < nums.Length; i++)
{
int another = target - nums[i];
if (table.ContainsKey(another))
{
int anotherIndex = (int)table[another];
result[] = anotherIndex > i ? i : anotherIndex;
result[] = anotherIndex < i ? i : anotherIndex;
return result;
}
else
{
if (!table.Contains(nums[i])) table.Add(nums[i], i);
}
}
throw new Exception("no answer");
}
# 题外话
这也是一段用Hashtable思想写的一段代码,我把它标记为bad hash,各位可以仔细推敲一下这里的问题(参考下面的测试用例)。
// bad hash: ignore duplication
public int[] TwoSum(int[] nums, int target)
{
System.Collections.Hashtable table = new System.Collections.Hashtable(nums.Length);
; i < nums.Length; i++)
table.Add(nums[i], i); // key can have duplications, so hash like this is a bad idea
; i < table.Count; i++)
{
int another = target - nums[i];
if (table.ContainsKey(another) && another != nums[i]) return new int[] { i, (int)table[another] };
}
throw new Exception("no answer");
}
# 测试用例
static void Main(string[] args)
{
_1TwoSum solution = new _1TwoSum();
Debug.Assert(Test.match(solution.TwoSum(, , }, ), , }), "wrong 1");
Debug.Assert(Test.match(solution.TwoSum(, , , }, ), , }), "wrong 2");
Debug.Assert(Test.match(solution.TwoSum(, }, ), , }), "wrong 3");
Debug.Assert(Test.match(solution.TwoSum(, , , }, ), , }), "wrong 4"); // duplication is result
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
;
Debug.Assert(Test.match(solution.TwoSum(test, target), , }), "wrong 5"); // duplication isn't result
Debug.Assert(Test.match(solution.TwoSum(, , , , , , }, ), , }), "wrong 6");
}
class Test
{
public static bool match(Array result, Array expect)
{
Debug.Assert(result.Length == expect.Length, "result's length isn't equal to expect's length");
; i < result.Length; i++)
if (!result.GetValue(i).Equals(expect.GetValue(i))) return false;
return true;
}
}
# 链接
Q: https://leetcode.com/problems/two-sum/
A: https://github.com/mofadeyunduo/LeetCode/tree/master/1TwoSum
(请多多支持我刚刚建立的GitHub和博客,谢谢,有问题可以邮件609092186@qq.com或者留言,我尽快回复)
LeetCode-1TwoSum(C#)的更多相关文章
- leetCode算法——1TwoSum(两数之和)
描述: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中 ...
- 我为什么要写LeetCode的博客?
# 增强学习成果 有一个研究成果,在学习中传授他人知识和讨论是最高效的做法,而看书则是最低效的做法(具体研究成果没找到地址).我写LeetCode博客主要目的是增强学习成果.当然,我也想出名,然而不知 ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
- [LeetCode] Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子字符串
Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...
- Leetcode 笔记 113 - Path Sum II
题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
随机推荐
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- WPF 微信 MVVM 【续】发送部分QQ表情
今天主要记录的就是发送QQ表情, WPF 微信 MVVM里写了,后期为了发送QQ表情,需要把TextBox替换为RichTextBox,接下来就说说替换的过程. 一.支持Binding的RichTex ...
- 【C#附源码】数据库文档生成工具支持(Excel+Html)
[2015] 很多时候,我们在生成数据库文档时,使用某些工具,可效果总不理想,不是内容不详细,就是表现效果一般般.很多还是word.html的.看着真是别扭.本人习惯用Excel,所以闲暇时,就简单的 ...
- PHP之GD函数的使用
本文讲解常用GD函数的应用 1.一个简单的图像 我们先看一个例子: <?php $w = 200; $h = 200; $img = imagecreatetruecolor($w,$h); $ ...
- ASP.NET Core 中文文档 第四章 MVC(4.6)Areas(区域)
原文:Areas 作者:Dhananjay Kumar 和 Rick Anderson 翻译:耿晓亮(Blue) 校对:许登洋(Seay) Areas 是 ASP.NET MVC 用来将相关功能组织成 ...
- ASP.NET MVC关于Ajax以及Jquery的无限级联动
---恢复内容开始--- 第一次发表博文,发表博文的目的是巩固自己的技术,也能够共享给大家.写的不好的地方,希望大家多给给意见.老司机勿喷 数据结构() NewsTypeId 新闻ID, NewsTy ...
- [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...
- ABP项目中使用Swagger生成动态WebAPI
本文是根据角落的白板报的<使用ABP实现SwaggerUI,生成动态webapi>一文的学习总结,感谢原文作者角落的白板报. 1 安装Swashbuckle.core 1.1 选择WebA ...
- Android Retrofit 2.0 使用-补充篇
推荐阅读,猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava 4.RxBus 5.Android MVP+Retrofit+RxJava实践小 ...
- SQL Server 2014聚集列存储索引
转发请注明引用和原文博客(http://www.cnblogs.com/wenBlog) 简介 之前已经写过两篇介绍列存储索引的文章,但是只有非聚集列存储索引,今天再来简单介绍一下聚集的列存储索引,也 ...