leetCode做题笔记二(4, 8)
2015-01-02 23:56
337 查看
LeetCode8, 手写atoi,一大堆判断。。。最好记录408ms,约为5%。
经验4:如何经济的判断溢出经验5:让不合法的输入第一时间return0;经验6:对于javascript里那一堆isxxx的函数,对应在Java的Character类下
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),直到两个序列中只含一个元素时为止,较小者即为所求的中位数。原因:应该在任何一个数列剩两个元素的时候就停止程序,因为有可能中位数恰好就是这两个元素的平均数,不能舍去。但这时要分析的情况太多,不优。
正确算法
这个算法的主要思想就在于找到一个数,这个数前面有(n+m)/2个数,不断递归求解即可
经验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个数,不断递归求解即可
相关文章推荐
- LeetCode做题笔记之四
- leetCode做题笔记二(26, 20,9)
- [LeetCode]Best Time to Buy and Sell Stock做题笔记
- 【LeetCode】Triangle做题笔记
- LeetCode 笔记系列十 Suduko
- LeetCode题目笔记(三) -- Median of Two Sorted Arrays
- LeetCode 笔记系列四 Remove Nth Node From End of List
- LeetCode 笔记系列二 Container With Most Water
- LeetCode题目笔记(二) -- Maximum Depth of Binary Tree
- ProjectEuler做题笔记(第1,2题)
- LeetCode 笔记系列12 Trapping Rain Water [复杂的代码是错误的代码]
- LeetCode 笔记系列八 Longest Valid Parentheses [lich你又想多了]
- LeetCode 笔记系列六 Reverse Nodes in k-Group [学习如何逆转一个单链表]
- 做题笔记
- LeetCode 笔记系列16.1 Minimum Window Substring [从O(N*M), O(NlogM)到O(N),人生就是一场不停的战斗]
- LeetCode 笔记系列13 Jump Game II [去掉不必要的计算]
- LeetCode 笔记系列五 Generate Parentheses
- LeetCode题目笔记(一) -- Minimum Depth Of Binary Tree
- LeetCode 笔记系列七 Substring with Concatenation of All Words
- LeetCode 笔记系列15 Set Matrix Zeroes [稍微有一点hack]