leetCode做题笔记二(4, 8)

  1. LeetCode8, 手写atoi,一大堆判断。。。最好记录408ms,约为5%

  经验4如何经济的判断溢出

  经验5:让不合法的输入第一时间return0;

  经验6:对于javascript里那一堆isxxx的函数,对应在JavaCharacter类下

public int atoi(String str) {
    if (str == null || str.length() == 0)
        return 0;
    int result = 1, i = 0, tmp, flag, sign = 0;
    int len = str.length();
    for (; i < len && !Character.isDigit(str.charAt(i)) && str.charAt(i) != '0'; i++){
        if (str.charAt(i) == '+') 
            ++sign;
        else
            if (str.charAt(i) == '-'){
                result = -1;
                ++sign;
            }
            else
                if (str.charAt(i) == ' ')
                    continue;
                else {
                    return 0;
                }
        if (sign > 0){
            if (i + 1 == len)
                return 0;
            if (!Character.isDigit(str.charAt(i + 1)))
                return 0;
        }
    }

    flag = result;
    result = result * (str.charAt(i) - '0');

        
    for (i++; i < len && Character.isDigit(str.charAt(i)); i++){
        tmp = result * 10 + (str.charAt(i) - '0') * flag;
        if (result > 214748364 || (result > 0 && tmp < 0))
            return Integer.MAX_VALUE;
        if (result < -214748364 || (result < 0 && tmp > 0))
            return Integer.MIN_VALUE;
        result = tmp;
    }
    return result;
    
}



2. LeetCode4 求两个升序数组的中位数

网上大部分解法都是错误的,和我犯了一样的错误。三个小时啊啊啊啊啊白费了

 

经验7:求平均数应该除以2.0

 

错误算法:

分别求出序列A B 的中位数,设为a b,求序列A B 的中位数过程

1)若a=b,则a b 即为所求中位数,算法结束。

2)若a<b,则舍弃序列A 中较小的一半,同时舍弃序列B 中较大的一半,要求舍弃的长度相等;

3)若a>b,则舍弃序列A 中较大的一半,同时舍弃序列B 中较小的一半,要求舍弃的长度相等;

在保留的两个升序序列中,重复过程1)、2)、3),直到两个序列中只含一个元素时为止,较小者即为所求的中位数。

原因:应该在任何一个数列剩两个元素的时候就停止程序,因为有可能中位数恰好就是这两个元素的平均数,不能舍去。但这时要分析的情况太多,不优。


正确算法

int findInsertPosition(int array[], int left, int right, int key){
    if (left == right){
        if (key <= array[left])
            return left;
        else
            return left + 1;
    }
    int mid = (left + right) / 2;
    if (array[mid] == key)
        return mid;
    else
        if (array[mid] > key)
            return findInsertPosition(array, left, mid, key);
        else
            return findInsertPosition(array, mid + 1, right, key);
}
public double findMedianSortedArrays(int A[], int B[]) {
    if (A.length == 0)
        return calArrayMid(B, 0, B.length - 1);
    if (B.length == 0)
        return calArrayMid(A, 0, A.length - 1);
    return _findMedianSortedArrays(A, 0, A.length - 1, B, 0, B.length - 1);
}


private double _findMedianSortedArrays(int[] a, int aLeft, int aRight, int[] b,
        int bLeft, int bRight) {
    // TODO Auto-generated method stub
    
    if (aLeft == aRight){
        if (bLeft == bRight)
            return (a[aLeft] + b[bLeft]) / 2.0;
        else {
            return calMedianByInsert(b, bLeft, bRight, a[aLeft]);
        }
    }
    if (bLeft == bRight)
        return calMedianByInsert(a, aLeft, aRight, b[bLeft]);
    
    int lena = (aRight - aLeft + 1) / 2;
    int lenb = (bRight - bLeft + 1) / 2;
    int lenDelete = lena > lenb ? lenb : lena;
    double mida = calArrayMid(a, aLeft, aRight);
    double midb = calArrayMid(b, bLeft, bRight);
    if (mida == midb) 
        return mida;
    else 
        if (mida < midb)
            return _findMedianSortedArrays(a, aLeft + lenDelete, aRight, b, bLeft, bRight - lenDelete);
        else 
            return _findMedianSortedArrays(a, aLeft, aRight - lenDelete, b, bLeft + lenDelete, bRight);
}
private double calArrayMid(int[] array, int left, int right) {
    int mid = (right - left + 1) / 2 + left;
    if (right - left == 1)
        return (array[left] + array[right]) / 2.0;
    if ((right - left + 1) % 2 == 0)
        return (array[mid] + array[mid - 1]) / 2.0;
    else
        return array[mid];
}

private double calMedianByInsert(int[] array, int left, int right, int key) {
    // TODO Auto-generated method stub
    int pos = findInsertPosition(array, left, right, key);
    
    if ((right - left + 2) % 2 != 0){
        int origPos = (right - left + 2) / 2 + left;
        if (pos == origPos)
            return key;
        else
            if (pos < origPos)
                return array[origPos - 1];
            else
                return array[origPos];
    }
    else {
        int origPos = (right - left + 2) / 2 + left - 1;
        if (pos < origPos)
            return (array[origPos - 1] + array[origPos]) / 2.0;
        else 
            if (pos == origPos || pos  == origPos + 1)
                return (array[origPos] + key) / 2.0;
            else 
                return (array[origPos + 1] + array[origPos]) / 2.0;
    }
}



这个算法的主要思想就在于找到一个数,这个数前面有(n+m)/2个数,不断递归求解即可


你可能感兴趣的:(java,LeetCode,算法)