您的位置:首页 > 其它

【leetcode】两数之和

2016-09-30 16:01 399 查看
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
;
int[] nvalues = new int
;

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();
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: