【leetcode】两数之和
https://leetcode.com/problems/two-sum/
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
Java:
版本1,暴力搜索(减少了部分搜索),预计打败全世界30%的答案。
public int[] twoSum(int[] nums, int target) {
int size = nums.length;
int size2 = size - 1;
for (int i=0; i<size2; i++) {
for (int j=i+1; j<size; j++) {
if ((nums[i] + nums[j]) == target) {
int[] pair = new int[2];
pair[0] = i;
pair[1] = j;
return pair;
}
}
}
int[] pair = new int[2];
return pair;
}
版本2,,通过HashMap解决循环匹配问题,预计打败全世界50%
HashMap<Integer, Integer> mm = new HashMap<Integer, Integer>();
int size = nums.length;
for (int i=0; i<size; i++) {
mm.put(nums[i], i);
}
Integer tmp = 0;
Integer v= 0;
for (int i=0; i<size; i++) {
tmp= target - nums[i];
v = mm.get(tmp);
if (v != null && v.intValue()!=i) {
int[] pair = new int[2];
pair[0] = i;
pair[1] = v;
return pair;
}
}
int[] pair = new int[2];
return pair;
版本3, 写到版本2的时候,肯定会想到把循环合并到一起执行,预计打败全世界58%。
HashMap<Integer, Integer> mm = new HashMap<Integer, Integer>();
int size = nums.length;
Integer tmp = 0;
Integer v= 0;
mm.put(nums[0], 0); for (int i=1; i<size; i++) {
tmp= target - nums[i];
v = mm.get(tmp);
if (v != null) {
int[] pair = new int[2];
pair[0] = i;
pair[1] = v;
return pair;
}
mm.put(nums[i], i);
} int[] pair = new int[2];
return pair;
版本4. 上面的代码已经不知道怎么优化,那么就减少int和Integer的转换吧,自己定制了一个IntHashMap,开始打败了68%,后面优化了hash的处理,提升到79%。
static final int MISSIDX = -1;
public int[] twoSum(int[] nums, int target) {
IntHashMap mm = new IntHashMap();
int size = nums.length;
int tmp = 0;
int v = 0;
mm.put(nums[0], 0);
for (int i = 1; i < size; i++) {
tmp = target - nums[i];
v = mm.get(tmp);
if (v != MISSIDX) {
int[] pair = new int[2];
if (tmp == nums[i]) {
pair[0] = v;
pair[1] = i;
} else {
pair[0] = i;
pair[1] = v;
}
return pair;
}
mm.put(nums[i], i);
} int[] pair = new int[2];
return pair;
} static class IntHashMap {
public static final int DEFAULT_INITIAL_CAPACITY = 16;
public static final int MAXIMUM_CAPACITY = 1073741824;
public static final float DEFAULT_LOAD_FACTOR = 0.75F;
private transient IntEntry[] table;
private transient int size;
private int threshold;
private final float loadFactor; public IntHashMap(int initialCapacity) {
this.loadFactor = 0.75F;
int capacity = 1;
while (capacity < initialCapacity) {
capacity <<= 1;
}
this.threshold = ((int)(capacity * loadFactor));
this.table = new IntEntry[capacity];
} public IntHashMap() {
this.loadFactor = 0.75F;
this.threshold = 12;
this.table = new IntEntry[16];
} protected int indexFor(int key, int length) {
return key & length - 1;
} public int get(int key) {
int i = indexFor(key, this.table.length);
IntEntry e = this.table[i];
while (true) {
if (e == null)
return MISSIDX;
if (e.key == key)
return e.value;
e = e.next;
}
} public void put(int key, int value) {
int i = indexFor(key, this.table.length);
addEntry(key, value, i);
} private void addEntry(int key, int value, int bucketIndex) {
IntEntry e = this.table[bucketIndex];
this.table[bucketIndex] = new IntEntry(key, value, e);
if (this.size++ >= this.threshold)
resize(2 * this.table.length);
} protected void resize(int newCapacity) {
IntEntry[] oldTable = this.table;
int oldCapacity = oldTable.length;
if (oldCapacity == 1073741824) {
this.threshold = 2147483647;
return;
} IntEntry[] newTable = new IntEntry[newCapacity];
transfer(newTable);
this.table = newTable;
this.threshold = ((int) (newCapacity * this.loadFactor));
} private void transfer(IntEntry[] newTable) {
IntEntry[] src = this.table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
IntEntry e = src[j];
if (e != null) {
src[j] = null;
do {
IntEntry next = e.next;
int i = indexFor(e.key, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
} public String toString() {
return Arrays.deepToString(this.table);
}
} static class IntEntry {
protected final int key;
protected int value;
protected IntEntry next; protected IntEntry(int k, int v, IntEntry n) {
this.value = v;
this.next = n;
this.key = k;
} public int getKey() {
return this.key;
} public int getValue() {
return this.value;
} public void setValue(int newValue) {
this.value = newValue;
} public boolean equals(Object o) {
if (!(o instanceof IntEntry))
return false;
IntEntry e = (IntEntry) o;
int eKey = e.getKey();
int eVal = e.getValue();
if (eKey == getKey()) {
return eVal == MISSIDX ? false : getValue() == MISSIDX ? true
: eVal == getValue();
}
return false;
} public int hashCode() {
return this.key ^ (this.value == MISSIDX ? 0 : value);
} public String toString() {
return "[" + key + "," + value + "]";
}
}
版本5. hashMap这个方向看来是尽头了,那用稀疏数组吧,貌似打败了87.62%
static final int MISSIDX = -1;
public int[] twoSum_0_4(int[] nums, int target) {
SparseIntArray mm = new SparseIntArray();
int size = nums.length;
int tmp = 0;
int v = 0;
mm.put(nums[0], 0);
for (int i = 1; i < size; i++) {
tmp = target - nums[i];
v = mm.get(tmp);
if (v != MISSIDX) {
int[] pair = new int[2];
if (tmp == nums[i]) {
pair[0] = v;
pair[1] = i;
} else {
pair[0] = i;
pair[1] = v;
}
return pair;
}
mm.put(nums[i], i);
} int[] pair = new int[2];
return pair;
} static final int[] EMPTY_INTS = new int[0];
static int idealByteArraySize(int need) {
for (int i = 4; i < 32; i++)
if (need <= (1 << i) - 12)
return (1 << i) - 12; return need;
}
static int idealIntArraySize(int need) {
return idealByteArraySize(need * 4) / 4;
}
static int binarySearch(int[] array, int size, int value) {
int lo = 0;
int hi = size - 1; while (lo <= hi) {
final int mid = (lo + hi) >>> 1;
final int midVal = array[mid]; if (midVal < value) {
lo = mid + 1;
} else if (midVal > value) {
hi = mid - 1;
} else {
return mid; // value found
}
}
return ~lo; // value not present
}
static class SparseIntArray {
private int[] mKeys;
private int[] mValues;
private int mSize;
public SparseIntArray() {
this(10);
}
public SparseIntArray(int initialCapacity) {
initialCapacity = idealIntArraySize(initialCapacity);
mKeys = new int[initialCapacity];
mValues = new int[initialCapacity];
mSize = 0;
}
public int get(int key) {
return get(key, MISSIDX);
}
public int get(int key, int valueIfKeyNotFound) {
int i = binarySearch(mKeys, mSize, key); if (i < 0) {
return valueIfKeyNotFound;
} else {
return mValues[i];
}
}
public void put(int key, int value) {
int i = binarySearch(mKeys, mSize, key); if (i >= 0) {
mValues[i] = value;
} else {
i = ~i; if (mSize >= mKeys.length) {
int n = idealIntArraySize(mSize + 1); int[] nkeys = new int[n];
int[] nvalues = new int[n]; System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
System.arraycopy(mValues, 0, nvalues, 0, mValues.length); mKeys = nkeys;
mValues = nvalues;
} if (mSize - i != 0) {
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
} mKeys[i] = key;
mValues[i] = value;
mSize++;
}
} public String toString() {
if (mSize <= 0) {
return "{}";
} StringBuilder buffer = new StringBuilder(mSize * 28);
buffer.append('{');
for (int i=0; i<mSize; i++) {
if (i > 0) {
buffer.append(", ");
}
int key = mKeys[i];
buffer.append(key);
buffer.append('=');
int value = mValues[i];
buffer.append(value);
}
buffer.append('}');
return buffer.toString();
}
}

【leetcode】两数之和的更多相关文章
- 【数据结构】Hash表简介及leetcode两数之和python实现
文章目录 Hash表简介 基本思想 建立步骤 问题 Hash表实现 Hash函数构造 冲突处理方法 leetcode两数之和python实现 题目描述 基于Hash思想的实现 Hash表简介 基本思想 ...
- LeetCode两数之和
LeetCode 两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是 ...
- leetcode两数之和go语言
两数之和(Go语言) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复 ...
- leetcode 两数之和 python
两数之和 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 1 ...
- leetcode - 两数之和Ⅳ 输入BST(653)
题目描述:给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true. 解题思路:根据二叉搜索树的特点,对二叉搜索树进行中序遍历可以得到一个从小到达排 ...
- Leetcode -- 两数之和Ⅰ
1. 两数之和 题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 示例:给定 nums = [2, 7, 11, 15 ...
- leetcode 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...
- Leetcode 两数之和 (散列表)
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...
- LeetCode两数之和-Python<一>
下一篇:LeetCode链表相加-Python<二> 题目:https://leetcode-cn.com/problems/two-sum/description/ 给定一个整数数组和一 ...
- leetCode:twoSum 两数之和 【JAVA实现】
LeetCode 两数之和 给定一个整数数组,返回两个数字的索引,使它们相加到特定目标. 您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素. 更多文章查看个人博客 个人博客地址:t ...
随机推荐
- php接口
如果要继承多个类的方法规范,用接口,因为抽象类只能继承一个: 如果要共享一个方法体内容,用抽象类: <?php //接口是为了规范实现它的子类,以达到统一的目的 //接口不能被实例化 inter ...
- hdu 1502 Regular Words
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502 思路:给定一个n,分别由n个a,b,c组成的字符串的所有前缀中a的个数大于等于b的个数大于等于c的个 ...
- awk分隔符设置技巧
Question:awk -F"[[]]"和awk -F"[][]"分割出的串为什么不一样呢? 按理说 -F"[]",[]表示匹配括号中的任 ...
- VS2012无法打开文件“kernel32.lib”问题的解决办法
后来经过百度搜索发现解决办法: 1.在项目属性[VC++目录]下的 [包含目录] 添加 $(WindowsSDK_IncludePath) ,在[库目录]添加$(WindowsSDK_LibraryP ...
- [MVC学习笔记]5.使用Controller来代替Filter完成登录验证(Session校验)
之前的学习中,在对Session校验完成登录验证时,通常使用Filter来处理,方法类似与前文的错误日志过滤,即新建Filter类继承ActionFilterAttribute类,重写On ...
- 常见开发需求之前端利器webstorm中的git和快捷键
需求 前端开发中我们最常用的一般是webstorm.hbuilder和sublime,因为以前使用过一段时间eclipse所以我对webstorm的感觉比较良好,再加上以前使用hbuilder维护 ...
- 浅谈SQLiteOpenHelper之onUpgrade例子
当你看到这个博文,首先你要了解onCreate这个创建方法,再来继续下文!(可以参考我的上一个博文http://www.cnblogs.com/896240130Master/p/6119616.ht ...
- Oracle协议适配器错误解决办法
在Oracle中新建了一个数据库,今天把它删了之后再登录SQL*PLUS就登不上去了,出现ORA-12560:TNS:协议适配器错误. ORA-12560: TNS: 协议适配器错误的解决方法 造成O ...
- tangram2.6(XE2)\framework框架加载包异常 调试的地方
添加以下的项目到项目组中, \tangram2.6(XE2)\framework\Core\Tangram_Core.dpk 调试此包的SysModuleMgr.pas的函数,本人还没有测试 func ...
- C#基础:值类型、引用类型与ref关键字
在C#中,ref的意思是按引用传递.可以参考C++: int a = 10, b = 20; void swap(int x, int y) { int temp = x; x = y; y = te ...