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】两数之和的更多相关文章

  1. 【数据结构】Hash表简介及leetcode两数之和python实现

    文章目录 Hash表简介 基本思想 建立步骤 问题 Hash表实现 Hash函数构造 冲突处理方法 leetcode两数之和python实现 题目描述 基于Hash思想的实现 Hash表简介 基本思想 ...

  2. LeetCode两数之和

    LeetCode 两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是 ...

  3. leetcode两数之和go语言

    两数之和(Go语言) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复 ...

  4. leetcode 两数之和 python

      两数之和     给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 1 ...

  5. leetcode - 两数之和Ⅳ 输入BST(653)

    题目描述:给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true. 解题思路:根据二叉搜索树的特点,对二叉搜索树进行中序遍历可以得到一个从小到达排 ...

  6. Leetcode -- 两数之和Ⅰ

    1. 两数之和 题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 示例:给定 nums = [2, 7, 11, 15 ...

  7. leetcode 两数之和 II - 输入有序数组

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...

  8. Leetcode 两数之和 (散列表)

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...

  9. LeetCode两数之和-Python<一>

    下一篇:LeetCode链表相加-Python<二> 题目:https://leetcode-cn.com/problems/two-sum/description/ 给定一个整数数组和一 ...

  10. leetCode:twoSum 两数之和 【JAVA实现】

    LeetCode 两数之和 给定一个整数数组,返回两个数字的索引,使它们相加到特定目标. 您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素. 更多文章查看个人博客 个人博客地址:t ...

随机推荐

  1. php接口

    如果要继承多个类的方法规范,用接口,因为抽象类只能继承一个: 如果要共享一个方法体内容,用抽象类: <?php //接口是为了规范实现它的子类,以达到统一的目的 //接口不能被实例化 inter ...

  2. hdu 1502 Regular Words

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502 思路:给定一个n,分别由n个a,b,c组成的字符串的所有前缀中a的个数大于等于b的个数大于等于c的个 ...

  3. awk分隔符设置技巧

    Question:awk -F"[[]]"和awk -F"[][]"分割出的串为什么不一样呢? 按理说 -F"[]",[]表示匹配括号中的任 ...

  4. VS2012无法打开文件“kernel32.lib”问题的解决办法

    后来经过百度搜索发现解决办法: 1.在项目属性[VC++目录]下的 [包含目录] 添加 $(WindowsSDK_IncludePath) ,在[库目录]添加$(WindowsSDK_LibraryP ...

  5. [MVC学习笔记]5.使用Controller来代替Filter完成登录验证(Session校验)

          之前的学习中,在对Session校验完成登录验证时,通常使用Filter来处理,方法类似与前文的错误日志过滤,即新建Filter类继承ActionFilterAttribute类,重写On ...

  6. 常见开发需求之前端利器webstorm中的git和快捷键

    需求   前端开发中我们最常用的一般是webstorm.hbuilder和sublime,因为以前使用过一段时间eclipse所以我对webstorm的感觉比较良好,再加上以前使用hbuilder维护 ...

  7. 浅谈SQLiteOpenHelper之onUpgrade例子

    当你看到这个博文,首先你要了解onCreate这个创建方法,再来继续下文!(可以参考我的上一个博文http://www.cnblogs.com/896240130Master/p/6119616.ht ...

  8. Oracle协议适配器错误解决办法

    在Oracle中新建了一个数据库,今天把它删了之后再登录SQL*PLUS就登不上去了,出现ORA-12560:TNS:协议适配器错误. ORA-12560: TNS: 协议适配器错误的解决方法 造成O ...

  9. tangram2.6(XE2)\framework框架加载包异常 调试的地方

    添加以下的项目到项目组中, \tangram2.6(XE2)\framework\Core\Tangram_Core.dpk 调试此包的SysModuleMgr.pas的函数,本人还没有测试 func ...

  10. C#基础:值类型、引用类型与ref关键字

    在C#中,ref的意思是按引用传递.可以参考C++: int a = 10, b = 20; void swap(int x, int y) { int temp = x; x = y; y = te ...