定义一个序列的“中数”为最大的整数x,使得序列中至少一半的数字大于等于x
牛牛想知道这个取出来的序列的中数最大可以是多少?
5,3,[30,1,2,31,9]
30
选前四个数字组成[30,1,2,31],中数为30
第一个参数n代表序列长度
第二个参数k代表取出的连续序列长度大于等于k
第三个参数vector a包含n个元素代表这个序列
class Solution { public: /** * 连续段的中数 * @param n int整型 * @param k int整型 * @param a int整型vector * @return int整型 */ int solve(int n, int k, vector<int>& a) { int l=0, r=INT_MAX, m; while(l+1 < r){ m = (l+r)>>1; int x=0, y=0, z=0; for(int i=0;i<k;i++) z += (a[i]>=m ? 1: -1); if(z >= 0){ l = m; continue; } for(int i=0;i<n-k;i++){ x += (a[i]>=m ? 1: -1); y = min(y, x); z += (a[i+k]>=m ? 1: -1); if(z >= y) break; } if(z >= y) l = m; else r = m; } return l; } };
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 * @param k int整型 * @param a int整型vector * @return int整型 */ static bool judge(vector<int>&a,int num,int k) { vector<int> vec; for(int i=0;i<a.size();i++) if(a[i]>=num) vec.push_back(i); int len; if(k%2==0) len=k/2; else len=k/2+1; //i=>j表示出现次数多于len个 那么研究第I个 与第j个 之间的位置 for(int i=0;i<vec.size();i++) for(int j=i+len-1;j<vec.size();j++) { //区间内满足出现二分之一以上 if((vec[j]-vec[i]+1)<=(j-i+1)*2) return true; } return false; } //研究Num是否是a的中数 int solve(int n, int k, vector<int>& a) { // write code her vector<int> arr=a; sort(arr.begin(),arr.end());//从小到大排序 //容易知道 最大的中数一定大于等于arr[0] 小于等于arr[len-1] //那么采取二分的方法 找到最后一个满足 是中数的数字 int l=0; int r=arr.size()-1; while(l<=r) //二分查找到最大的中数 { int mid=(l+r)/2; int val=arr[mid]; //可能的中数 if(judge(a,val,k)) //如果val是中数 l=mid+1; else r=mid-1; } return arr[l-1]; } };