您的位置:首页 > 编程语言 > Java开发

leetCode做题笔记二(4, 8)

2015-01-02 23:56 337 查看
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个数,不断递归求解即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 算法 LeetCode