arr[0]<arr[1],那么arr[0]是局部最小;如果arr[N-1]<arr[N-2],那么arr[N-1]是局部
最小;如果0<i<N-1,既有arr[i]<arr[i-1]又有arr[i]<arr[i+1],那么arr[i]是局部最小。
给定无序数组arr,已知arr中任意两个相邻的数都不相等,写一个函数,只需返回arr中任
意一个局部最小出现的位置即可。
if(n<1||a.size()==0)
return -1;
if(n==1)
return 0;
int l=0,r=n-1;
if(a[l]<a[l+1])
return l;
if(a[r]<a[r-1])
return r;
l++,r--;
int mid=(l+r)/2;
while(l!=r){
int mid=(l+r)/2;
if(a[mid]>a[mid-1]){
r=mid-1;
}
else if(a[mid]>a[mid+1]){
l=mid+1;
}
else{
return mid;
}
}
return l;
}
2.给定一个double类型的数组arr,其中的元素可正可负可0,返回子数组累乘的最大乘积。
例如arr=[-2.5,4,0,3,0.5,8,-1],子数组[3,0.5,8]累乘可以获得最大的乘积12,
所以返回12。
if(a==NULL||n<=0)
return -1;
double mx=a[0],mn=a[0],res=a[0];
for(int i=1;i<n;i++){
double nNewm=mx*a[i];
double nNewn=mn*a[i];
mx=max(max(nNewm,nNewn),a[i]);
mn=min(min(nNewm,nNewn),a[i]);
res=max(mx,res);
}
return res;
}
3.给定一棵完全二叉树的头节点head,返回这棵树的节点个数。如果完全二叉树的节点数为N,
请实现时间复杂度低于O(N)的解法。
int data;
Node* lch;
Node* rch;
}Node;
int creatTree(Node **pNode){
int x;
cin>>x;
if(x<0){
*pNode=NULL;
return 0;
}
*pNode=new Node();
(*pNode)->data=x;
creatTree(&((*pNode)->lch));
creatTree(&((*pNode)->rch));
return 1;
}
void dfs(Node *head){
if(head==NULL)
return;
cout<<head->data<<" ##";
dfs(head->lch);
dfs(head->rch);
}
void dfs2(Node *head){
if(head==NULL)
return;
dfs2(head->lch);
dfs2(head->rch);cout<<head->data<<" !!";
}
void dfs1(Node *head){
if(head==NULL)
return;
dfs1(head->lch);
cout<<head->data<<" ";
dfs1(head->rch);
}
int NodeNum(Node * head,int hight){
if(head==NULL)
return 0;
if(hight==1)
return 1;
cout<<"@@"<<endl;
Node *pNode=head->rch;
int h=1;
while(pNode!=NULL){
pNode=pNode->lch;
h++;
}
cout<<"!!"<<h<<endl;
if(h==hight){
cout<<"h==hight "<<pow(2,h-1)<<endl;
return pow(2,h-1)+NodeNum(head->rch,hight-1);
}
else{
cout<<"h!=hight "<<pow(2,h)<<endl;
return pow(2,h-1)+NodeNum(head->lch,hight-1);
}
}
int main(){
Node *Head=new Node();
while(creatTree(&Head)){
Node *pNode=Head;
int h=1;
while(pNode->lch!=NULL){
pNode=pNode->lch;
h++;
}
int num=NodeNum(Head,h);
cout<<"num="<<num<<endl;
}
}
4.给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数。
例如:
arr1 = {1,2,3,4};
arr2 = {3,4,5,6};
一共8个数则上中位数是第4个数,所以返回3。
arr1 = {0,1,2};
arr2 = {3,4,5};
一共6个数则上中位数是第3个数,所以返回2。
要求:时间复杂度O(logN)
// int num;
int n=(r1-l1+1);cout<<" n="<<n<<endl;
if(n==1)
return a[l1] < b[l2] ? a[l1] : b[l2];
if(n%2==0){//o
int mda=(r1+l1)/2;
int mdb=(r2+l2)/2;//cout<<"md=("<<mda<<" "<<mdb<<")"<<a[mda]<<" "<<b[mdb]<<endl;
if(a[mda]==b[mdb])
return a[mda];
else if(a[mda]>b[mdb]){
return upmid(a,b,l1,mda,mdb+1,r2);
}
else{//a[md]<b[md]
return upmid(a,b,mda+1,r1,l2,mdb);
}
}
else{//j
int mda=(r1+l1)/2;
int mdb=(r2+l2)/2;
if(a[mda]==b[mdb])
return a[mda];
else if(a[mda]>b[mdb]){
return upmid(a,b,l1,mda,mdb,r2);
}
else{//a[md]<b[md]
return upmid(a,b,mda,r1,l2,mdb);
}
}
}
void findNum(int a[],int b[],int n){
if(n==0||a==NULL||b==NULL)//len1!=len2
cout<<"input you wenti"<<endl ;
else{
int num=upmid(a,b,0,n-1,0,n-1);
cout<<"upmidNum="<<num<<endl;
}
}
例如:
arr1 = {1,2,3,4,5};
arr2 = {3,4,5};
K = 1;
因为1为所有数中最小的,所以返回1;
arr1 = {1,2,3};
arr2 = {3,4,5,6};
K = 4;
因为3为所有数中第4小的数,所以返回3;
要求:如果arr1的长度为N,arr2的长度为M,时间复杂度请达到O(log(min{M,N}))。
int upmid(int a[],int b[],int l1,int r1,int l2,int r2){// n======0->n-1
// int num;
int n=(r1-l1+1);//cout<<" n="<<n<<endl;
if(n==1)
return a[l1] < b[l2] ? a[l1] : b[l2];
if(n%2==0){//o
int mda=(r1+l1)/2;
int mdb=(r2+l2)/2;//cout<<"md=("<<mda<<" "<<mdb<<")"<<a[mda]<<" "<<b[mdb]<<endl;
if(a[mda]==b[mdb])
return a[mda];
else if(a[mda]>b[mdb]){
return upmid(a,b,l1,mda,mdb+1,r2);
}
else{//a[md]<b[md]
return upmid(a,b,mda+1,r1,l2,mdb);
}
}
else{//j
int mda=(r1+l1)/2;
int mdb=(r2+l2)/2;
if(a[mda]==b[mdb])
return a[mda];
else if(a[mda]>b[mdb]){
return upmid(a,b,l1,mda,mdb,r2);
}
else{//a[md]<b[md]
return upmid(a,b,mda,r1,l2,mdb);
}
}
}
int findNum(int a[],int b[],int n,int m,int k){
//a < b传进来时保证大小
if(a==NULL||b==NULL||n<=0||m<=0||k<=0||k>m+n)
return -1;
if(k<=n){
return upmid(a,b,0,k-1,0,k-1);
}
else if(k>n&&k<=m){
int lNo=k-n-1;
int rNo=k;
if(a[lNo]>b[n-1])
return a[lNo];
else
return upmid(a,b,0,n-1,lNo,rNo);
}
else{//k>m && k<=m+n
int x=k-n-1;
int y=m-1;
int l=k-m-1;
int r=n-1;
if(a[l]>=b[m-1])
return a[l];
else if(b[x]>=a[n-1])
return b[x];
else
return upmid(a,b,l+1,r,x+1,y);
}
}
//-----------------------------------------------------------------------------华丽分割线---------------------------------------------------------------------------------------------老师的标准答案
//1--------------------------------------
public int getLessIndex(int[] arr) {
if (arr == null || arr.length == 0) {
return -1; // no exist
}
if (arr.length == 1 || arr[0] < arr[1]) {
return 0;
}
if (arr[arr.length - 1] < arr[arr.length - 2]) {
return arr.length - 1;
}
int left = 1;
int right = arr.length - 2;
int mid = 0;
while (left < right) {
mid = (left + right) / 2;
if (arr[mid] > arr[mid - 1]) {
right = mid - 1;
} else if (arr[mid] > arr[mid + 1]) {
left = mid + 1;
} else {
return mid;
}
}
return left;
}
//2------------------------------------------------
public double maxProduct(double[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
double max = arr[0];
double min = arr[0];
double res = arr[0];
double maxEnd = 0;
double minEnd = 0;
for (int i = 1; i < arr.length; ++i) {
maxEnd = max * arr[i];
minEnd = min * arr[i];
max = Math.max(Math.max(maxEnd, minEnd), arr[i]);
min = Math.min(Math.min(maxEnd, minEnd), arr[i]);
res = Math.max(res, max);
}
return res;
}
//3---------------------------------------------------------
public int nodeNum(Node head) {
if (head == null) {
return 0;
}
return bs(head, 1, mostLeftLevel(head, 1));
}
public int bs(Node node, int l, int h) {
if (l == h) {
return 1;
}
if (mostLeftLevel(node.right, l + 1) == h) {
return (1 << (h - l)) + bs(node.right, l + 1, h);
} else {
return (1 << (h - l - 1)) + bs(node.left, l + 1, h);
}
}
public int mostLeftLevel(Node node, int level) {
while (node != null) {
level++;
node = node.left;
}
return level - 1;
}
//4-----------------------------------------------------
public static int getUpMedian(int[] arr1, int[] arr2) {
if (arr1 == null || arr2 == null || arr1.length != arr2.length) {
throw new RuntimeException("Your arr is invalid!");
}
return findProcess(arr1, 0, arr1.length - 1, arr2, 0, arr2.length - 1);
}
public static int findProcess(int[] arr1, int start1, int end1, int[] arr2,
int start2, int end2) {
if (start1 == end1) {
return Math.min(arr1[start1], arr2[start2]);
}
// 元素个数为奇数,则offset为0;元素个数为偶数,则offset为1;
int offset = ((end1 - start1 + 1) & 1) ^ 1;
int mid1 = (start1 + end1) / 2;
int mid2 = (start2 + end2) / 2;
if (arr1[mid1] > arr2[mid2]) {
return findProcess(arr1, start1, mid1, arr2, mid2 + offset, end2);
} else if (arr1[mid1] < arr2[mid2]) {
return findProcess(arr1, mid1 + offset, end1, arr2, start2, mid2);
} else {
return arr1[mid1];
}
}
//5-------------------------------------------------
public static int findKthNum(int[] arr1, int[] arr2, int kth) {
if (arr1 == null || arr2 == null) {
throw new RuntimeException("Your arr is invalid!");
}
if (kth < 1 || kth > arr1.length + arr2.length) {
throw new RuntimeException("K is invalid!");
}
int[] longArr = arr1.length >= arr2.length ? arr1 : arr2;
int[] shortArr = arr1.length < arr2.length ? arr1 : arr2;
int lenL = longArr.length;
int lenS = shortArr.length;
if (kth <= lenS) {
return getUpMedian(shortArr, 0, kth - 1, longArr, 0, kth - 1);
}
if (kth > lenL) {
if (shortArr[kth - lenL - 1] >= longArr[lenL - 1]) {
return shortArr[kth - lenL - 1];
}
if (longArr[kth - lenS - 1] >= shortArr[lenS - 1]) {
return longArr[kth - lenS - 1];
}
return getUpMedian(shortArr, kth - lenL, lenS - 1, longArr, kth - lenS, lenL - 1);
}
if (longArr[kth - lenS - 1] >= shortArr[lenS - 1]) {
return longArr[kth - lenS - 1];
}
return getUpMedian(shortArr, 0, lenS - 1, longArr, kth - lenS, kth - 1);
}
public static int getUpMedian(int[] arr1, int start1, int end1, int[] arr2,
int start2, int end2) {
if (start1 == end1) {
return Math.min(arr1[start1], arr2[start2]);
}
int offset = ((end1 - start1 + 1) & 1) ^ 1;
int mid1 = (start1 + end1) / 2;
int mid2 = (start2 + end2) / 2;
if (arr1[mid1] > arr2[mid2]) {
return getUpMedian(arr1, start1, mid1, arr2, mid2 + offset, end2);
} else if (arr1[mid1] < arr2[mid2]) {
return getUpMedian(arr1, mid1 + offset, end1, arr2, start2, mid2);
} else {
return arr1[mid1];
}
}