17.已知一个乱序整数数组
求该数组排序相邻两数的最大间隔
要求时间复杂度为o(N)
时间复杂度的要求基本把先排序的方法滤掉了。
思路如下;
先遍历一遍找出最大,最小,设定gap=(max-min)/n,设立k个桶,记录每个桶中最大最小值,然后顺序比较各个桶的最大最小。
这里把遍历一遍找最大最小示范一下,这个最大最小问题是编程之美上的原题。
#include <iostream>
using namespace std;
struct mm
{
int max;
int min;
};
struct mm getMaxMin(int *arr, int b, int e);
int main()
{
int arr[6]={5,6,8,3,7,9};
struct mm m = getMaxMin(arr,0,5);
cout<<m.max<<"\t"<<m.min<<endl;
return 0;
}
struct mm getMaxMin(int *arr, int b,int e)
{
struct mm m;
if((e-b)<=1)
{
if(arr[b]<arr[e])
{
m.max = arr[e];
m.min = arr[b];
}else
{
m.max = arr[b];
m.min = arr[e];
}
return m;
}
struct mm mL,mR;
mL = getMaxMin(arr, b, b+(e-b)/2);
mR = getMaxMin(arr, b+(e-b)/2+1,e);
if(mL.max>mR.max)
m.max = mL.max;
else
m.max = mR.max;
if(mL.min<mR.min)
m.min = mL.min;
else
m.min = mR.min;
return m;
}
显然这是标准的递归做法
也利用了分治的思想
18.求两个相同大小已排序数组的中位数
找出两个等长数组的中位数,算法复杂度O(lgN)
一看到logN这种条件反射就是要做二分分治和递归的.
思路
若m1=m2,则m1为2n个数的中位数,
若m1!=m2,注意到已排序的特性,则中位数位于较大数组的下半部和另一数组的上半部
#include <iostream>
using namespace std;
int findMean(int *a, int m, int *b,int n);
int getMean(int *a, int n);
int main()
{
int a[]={1,2,3,4,5,6,7,8,9,10};
int b[]={11,12,13,14,15,16,17,18,19,20};
cout<<findMean(a, 10,b, 10)<<endl;
return 0;
}
int findMean(int *a,int m, int *b, int n)
{
int ma,mb;
ma = getMean(a, m);
mb = getMean(b, n);
if(ma==mb) return ma;
else if(ma>mb&&m>1&&n>1)
return findMean(a,m/2,&b[n/2],n/2);
else if(ma<=mb&&m>1&&n>1)
return findMean(&a[m/2],m/2,b,n/2);
else return (ma+mb)/2;
}
int getMean(int *a, int n)
{
if(!n) return 0;
int mean=0;
for(int i=0;i<n;++i)
mean+=a[i];
return mean/n;
}
19.数组合并
这是归并算法的核心模块
面试金典255页原题
思路是从末尾开始合并比较方便。
/**
* Created by tangchen on 2016/10/6.
*/
public class MergeArray {
public static void merge(int[] a, int[] b, int lastA, int lastB)
{
int indexA = lastA-1;
int indexB = lastB-1;
int indexMerged = lastB + lastA -1;
while(indexA>=0 && indexB >=0)
{
if(a[indexA]>b[indexB])
{
a[indexMerged] = a[indexA];
indexA--;
}else
{
a[indexMerged] = b[indexB];
indexB--;
}
indexMerged--;
}
while(indexB>=0)
{
a[indexMerged] = b[indexB];
indexMerged--;
indexB--;
}
}
}
20.全排序算法
也称permutation
或者叫幂集替换
面试金典229页原题
#include <iostream>
#include <cstring>
using namespace std;
void getPerm(char *s, int i, int n);
void mySwap(char *a, char *b);
int main()
{
char str[4]="abc";
getPerm(str, 0,2);
cout<<endl;
return 0;
}
void getPerm(char *s, int i, int n)
{
if(i==n)
{
//cout<<s<<" ";
for(int j=0;j<=n;j++) cout<<s[j];
cout<<endl;
return;
}
for(int j=i;j<=n;j++)
{
mySwap(&s[i],&s[j]);
getPerm(s, i+1, n);
mySwap(&s[i],&s[j]);
}
}
void mySwap(char *a, char *b)
{
char ch=*a;
*a=*b;
*b=ch;
}