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. MSSQL 查询表空间

    1. exec sp_spaceused '表名'            (SQL统计数据,大量事务操作后可能不准) 2. exec sp_spaceused '表名', true       (更新 ...

  2. 基于NPOI的报表引擎——ExcelReport

    前言 其实现在说ExcelReport是报表引擎还为时尚早,但该组件我既然要决心维护下去,这便算是初衷吧! 1.现在,ExcelReport能为你做什么呢? 如果,你有导出数据到Excel的需求,Ex ...

  3. 复利计算--结对项目<04-11-2016> 1.0.0 lastest 阶段性完工~

    结对项目:Web复利计算 搭档博客地址:25江志彬  http://www.cnblogs.com/qazwsxedcrfv/ 个人摘要: (2016-04-09-12:00)补充:之前传送门没做好, ...

  4. Hibernate的抓取策略

    立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get())延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()) 类级 ...

  5. php 冒泡 快速 选择 插入算法 四种基本算法

    php四种基础算法:冒泡,选择,插入和快速排序法 来源:PHP100中文网 | 时间:2013-10-29 15:24:57 | 阅读数:120854 [导读] 许多人都说 算法是程序的核心,一个程序 ...

  6. 【MongoDB初识】-安装篇

    1.首先MongoDB官网:http://www.mongodb.org,下载mongoDB 2.解压安装 自己安装在E:\mongdb 3.提示otfix KB2731284 or later up ...

  7. 简单CSS3动画制作

    本贴已重新编辑至http://www.cnblogs.com/fastmover/p/4977358.html 最近需要用到了一些CSS3动画,基本用Animate.css(https://githu ...

  8. zookeeper心跳机制流程梳理

    zookeeper心跳机制流程梳理 Processor链Chain protected void setupRequestProcessors() { RequestProcessor finalPr ...

  9. 1.2 Quartz 2D 内存管理

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书”   通过 Product -> Analyze 来进行静态分析   可以使用Quar ...

  10. webform 简单控件

    html中12个表单元素添加runat="server"后称为控件 Lable 编译之后是 <span></span> 属性:CssClass  编译成 c ...