好久没有刷过题了,刚好最近刷了几道,然后也复习下vector的用法.
题目是给了两个数组,然后求中位数,可以看成是求最K小的数,如果时间上没有要求的话,可以用暴力遍历就行。
因为已知数组是排好序的,所以只需要将两个数组的进行O(max(n,m))的遍历,然后根据数组长度的奇偶性,输出中位数,然后样例是doube类型,输出的时候要强转。这种方法要格外申请数组,所以内存上还是有消耗的。
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int n = nums1.size(); int m = nums2.size(); int count = 0; int len = (n+m)/2; int mmap[n+m+10]; int i,j; for(i=0,j=0;i<n && j<m;){ if(nums1[i] < nums2[j]){ mmap[count++] = nums1[i++]; } else{ mmap[count++] = nums2[j++]; } } for(;i<n;i++){ mmap[count++] = nums1[i]; } for(;j<m;j++){ mmap[count++] = nums2[j]; } if((n+m)%2 == 1) return mmap[(n+m)/2]*1.0; else return (mmap[(n+m)/2] + mmap[(n+m)/2-1])/2.0; } };
还有另外一种可以根据折半的查找,类似于二分吧~
主要是分两种情况,
数组A和B,首先将数组折半,中位数分别是m1,m2,下标分别是i1,i2
然后
如果 i1 + i2 < k
如果m1 > m2,那么中位数不在B数组的前半段,则此时需要更新求第K = K - i2 - 1小的数;
如果m1 <= m2,那么同理中位数不在A数组的前半段,则此时需要更新求K = K - i1 - 1小的数;
如果 i1 + i2 >= k
如果m1 > m2,那么中位数不在A数组的后半段,继续求第K小的数;
如果m1 <= m2,那么中位数不在B数组的后半段,继续求第K小的数;
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int n = nums1.size() + nums2.size(); vector<int> aa(nums1.begin(),nums1.begin() + nums1.size()); vector<int> bb(nums2.begin(),nums2.begin() + nums2.size()); if(n%2 == 1){ return findk(nums1,nums2,n/2); } else{ return (findk(nums1,nums2,n/2) + findk(aa,bb,n/2-1) )/ 2.0; } } double findk(vector<int>& nums1,vector<int>& nums2,int k){ if(nums1.size() == 0){ return nums2[k]; } if(nums2.size() == 0){ return nums1[k]; } int n = nums1.size(); int m = nums2.size(); int i1 = n/2; int i2 = m/2; int m1 = nums1[i1]; int m2 = nums2[i2]; if(i1 + i2 < k){ if(m1>m2){ nums2.erase(nums2.begin(),nums2.begin()+i2 + 1); return findk(nums1,nums2,k-i2-1); } else{ nums1.erase(nums1.begin(),nums1.begin() + i1 + 1); return findk(nums1,nums2,k-i1-1); } } else{ if(m1>m2){ int tx = i1; if(i1 == 0 && nums1.size() == 1) tx = i1 + 1; while(tx > 0 && nums1.size() !=0){ nums1.pop_back(); tx--; } return findk(nums1,nums2,k); } else{ int tx = i2; if(i2 ==0 && nums2.size() == 1) tx = i2 + 1; while(tx > 0 && nums2.size() != 0){ nums2.pop_back(); tx--; } return findk(nums1,nums2,k); } } return 0.0; } };
写代码的时候再vector.erase的时候,一直用的是
ums2.erase(nums2.end()-i2,nums2.end());
然后如果当数组i2=0,然后nums2.size == 1 的时候,会不能清空,会进入死循环。
priority_queue<int ,vector<int >,less<int> >que; //从大到小排列 priority_queue<int ,vector<int >,greater<int> >que;//从小到大排列
顺便记下优先队列,之前写广搜经常用到,现在好久没有刷题了,都不记得了。。。。