LeetCode8, 手写atoi,一大堆判断。。。最好记录408ms,约为5%。
经验4:如何经济的判断溢出
经验5:让不合法的输入第一时间return0;
经验6:对于javascript里那一堆isxxx的函数,对应在Java的Character类下
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个数,不断递归求解即可