Java
1.挨个点名
两个数组各使用一个指针,点名点过总数的一半就是中位数了,每次点两者中最小的数,如果指针超出范围则不再点。
思路还是不太清晰,因此代码写得很乱,为解决指针超出范围的问题打了很多补丁。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int lp = 0, rp = 0, n1 = nums1.length, n2 = nums2.length;
double ans = 0;
//排除空数组的问题
if(n1 == 0){
if(n2%2==0){
ans = (nums2[n2/2-1] + nums2[n2/2])/2.0;
}
else{
ans = nums2[n2/2];
}
return ans;
}
if(n2==0){
if(n1%2==0){
ans = (nums1[n1/2-1] + nums1[n1/2])/2.0;
}
else{
ans = nums1[n1/2];
}
return ans;
}
//首先是偶数个数的情况
if((n1 + n2)%2==0){
for(int i = 0;i<(n1 + n2)/2; i++){
if(i!=(n1+n2)/2-1){//没有触及中位数时
if(nums1[lp]<nums2[rp]){
lp++;
}
else{
rp++;
}
//下面两个if是为了解决某个数组数到头的情况
if(lp >= n1){
ans = (nums2[rp + (n1 + n2)/2 - 1 - i - 1] + nums2[rp + (n1 + n2)/2 - 1 - i])/2.0;
break;
}
if(rp >= n2){
ans = (nums1[lp + (n1 + n2)/2 - 1 - i - 1] + nums1[lp + (n1 + n2)/2 - 1 - i])/2.0;
break;
}
}
else{//触及中位数:此时lp或rp中较小的数与下一位的平均就是“中位数”
if(nums1[lp]<nums2[rp]){
ans = nums1[lp];
lp++;
}
else{
ans = nums2[rp];
rp++;
}
if(lp < n1 && rp < n2){//这里又排除了指针超出范围的情况
if(nums1[lp]<nums2[rp]){
ans = (ans + nums1[lp])/2.0;
}
else{
ans = (ans + nums2[rp])/2.0;
}
}
else if(lp>=n1){
ans = (ans + nums2[rp])/2.0;
}
else{
ans = (ans + nums1[lp])/2.0;
}
}
}
}
else{//总数是奇数的情况
for(int i = 0;i<(n1 + n2)/2+1; i++){
if(i!=(n1+n2)/2){
if(nums1[lp]<nums2[rp]){
lp++;
}
else{
rp++;
}
if(lp >= n1){
ans = nums2[rp + (n1 + n2)/2 - i - 1];
break;
}
if(rp >= n2){
ans = nums1[lp + (n1 + n2)/2 - i - 1];
break;
}
}
else{
if(lp < n1 && rp < n2){
if(nums1[lp]<nums2[rp]){
ans = nums1[lp];
}
else{
ans = nums2[rp];
}
}
else if(lp >= n1){
ans = nums2[rp];
}
else{
ans = nums1[lp];
}
}
}
}
return ans;
}
}
好像更暴力的解法是,两个数组合并,再排序。。不过这样空间变大了。。
2.官方解题思路
建议用二分查找实现,我在解题前思考过,但没怎么想明白,就拿最直观的方法解了。。题解的思路也没仔细看,脑子不工作了。。。。。。。。。。。。。。。。。。。。。。。。。。。
3.知识点
1.时间复杂度和空间复杂度的定义。。。
2.注意整数除法得到的结果仍是整数。。。又吃一亏
3.思路弄清楚再写吧,不然总是给代码打补丁,搞得脑子混乱。。。。