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

 

posted @ 2016-09-30 16:01  明将军  Views(383)  Comments(0Edit  收藏  举报
恨怨悲苦憎怒嗔、仁爱慈孝耻义廉。是故恨人所以得仁,无爱者必不怨,不慈者必无悲,孝而有苦,憎后耻来,义自怒生,廉人心嗔。夹天地七大苦,破人情七大碍,遂舍善恶之心,得称剑神。