学习笔记2

1.二分查找

int binarySearch(int *a,int n,int x)
{
    int left=0,right=n-1;
    while(left<=right)
    {
        int mid=left+(right-left)/2;
        if(x<a[mid])right=mid-1;
        else if(x>a[mid])left=mid+1;
        else return mid;
    }
    return -1;
}

变形

//求最小的i使得a[i]等于x。
int binarySearch(int *a,int n,int x)  
{  
    int left=0,right=n-1;  
    while(left<right-1)  
    {  
        int mid=left+(right-left)/2;  
        if(a[mid]<x)left=mid+1;  
        else right=mid;    
    }
    if(a[left]==x)return left;
    if(a[right]==x)return right;
    return -1;  
}  

//求最大的i使得a[i]等于x。
int binarySearch(int *a,int n,int x)  
{  
    int left=0,right=n-1;  
    while(left<right-1)  
    {  
        int mid=left+(right-left)/2;  
        if(x<a[mid])right=mid-1;  
        else left=mid;    
    }
    if(a[right]==x)return right;
    if(a[left]==x)return left;
    return -1;  
}  

//求最大的i使得a[i]小于x。
int binarySearch(int *a,int n,int x)  
{  
    int left=0,right=n-1;  
    while(left<right-1)  
    {  
        int mid=left+(right-left)/2;  
        if(x<=a[mid])right=mid-1;  
        else left=mid;    
    }
    if(a[right]<x)return right;
    if(a[left]<x)return left;
    return -1;  
}  

//求最小的i使得a[i]大于x。
int binarySearch(int *a,int n,int x)  
{  
    int left=0,right=n-1;  
    while(left<right)  
    {  
        int mid=left+(right-left)/2;  
        if(a[mid]<=x)left=mid+1;  
        else right=mid;    
    }
    if(a[left]>x)return left;
    if(a[right]>x)return right;
    return -1;
}

//若x在数组中,返回x的位置;若x不在数组中,返回x的插入位置。
int binarySearch(int *a,int n,int x)  
{  
    int left=0,right=n-1;  
    while(left<right)  
    {  
        int mid=left+(right-left)/2;  
        if(a[mid]<x)left=mid+1;  
        else if(a[mid]>x)right=mid;
        else return mid;
    }
    return left;
}  

//求绝对值最小的元素的位置。
int binarySearch(int *a,int n)  
{
    if(a[0]>=0)return 0;
    if(a[n-1]<=0)return n-1;
    int left=0,right=n-1;
    while(left<right)  
    {  
        int mid=left+(right-left)/2;  
        if(a[mid]<0)left=mid+1;  
        else right=mid;
    }
    if(a[left]<-a[left-1])return left;
    else return left-1;
}

2.旋转数组的最大(小)数

int max(int *a,int n)
{
    int left=0,right=n-1;
    if(a[left]<a[right])return a[right];
    while(left<right-1)
    {
        int mid=left+(right-left)/2;
        if(a[mid]>a[left])left=mid;
        else right=mid;
    }
    return a[left];
}

int min(int *a,int n)
{
    int left=0,right=n-1;
    if(a[left]<a[right])return a[left];
    while(left<right-1)
    {
        int mid=left+(right-left)/2;
        if(a[mid]>a[left])left=mid;
        else right=mid;
    }
    return a[right];
}

3.二叉搜索树的后序遍历序列

bool f(int *a,int n)
{
    if(n==0)return true;
    int i;
    for(i=0;i<=n-2;++i)
    {
        if(a[i]>a[n-1])break;
    }
    for(int j=i;j<=n-2;++j)
    {
        if(a[j]<a[n-1])return false;
    }
    return f(a,i)&&f(a+i,n-1-i);
}

4.寻找发帖“水王”(编程之美)

int f(int *a,int n)
{
    int i,nTimes,candidate;
    for(i=nTimes=0;i<m;++i)
    {
        if(nTimes==0)
        {
            candidate=a[i];
            ++nTimes;
        }
        else
        {
            if(a[i]==candidate)++nTimes;
            else --nTimes;
        }
    }
    return candidate;
}

5.给定一数组a[N],我们希望构造数组b[N],其中b[j]=a[0]*a[1]…a[N-1]/a[j],在构造过程中,不允许使用除法;要求O(1)空间复杂度和O(n)的时间复杂度;除遍历计数器与a[N]、b[N]外,不可使用新的变量(包括栈临时变量、堆空间和全局静态变量等);实现程序(主流编程语言任选)实现并简单描述。

a:a0*a1*a2*a3*(a4*a3*a2*a1),a1,a2,a3,a4*a3*a2*a1*(a0*a1*a2*a3*a4*a3*a2*a1)

b:a4*a3*a2*a1,a0*(a4*a3*a2),(a0*a1)*(a4*a3),(a0*a1*a2)*a4,a0*a1*a2*a3

void f(int *a,int *b,int n)  
{  
    for(int i=0;i<n;++i)b[i]=1;
    for(int i=1;i<n;++i)
    {
        b[i]*=a[0];
        a[0]*=a[i];
        b[n-1-i]*=a[n-1];
        a[n-1]*=a[n-1-i];
    }
}
6.分解质因数
vector<int> f(int n)
{
    vector<int> result;
    if(n<2)return result;
    int a=2;
    while(a*a<=n)
    {
        while(n%a==0)
        {
            result.push_back(a);
            n/=a;
        }
        ++a;
    }
    if(n>1)result.push_back(n);
    return result;
}

7.不用加减乘除做加法

int add(int a,int b)
{
    int tmp;
    do
    {
        tmp=a^b;
        b=(a&b)<<1;
        a=tmp;
    }while(b);
    return a;
}

8.请把一个整形数组中重复的数字去掉。例如:1,2,0,2,-1,999,3,999,88,答案应该是:1,2,0,-1,999,3,88。

vector<int> f(vector<int> vec)
{
    vector<int> result;
    unordered_set<int> set;
    for(int i=0;i<vec.size();++i)
    {
        if(set.find(vec[i])==set.end())
        {
            set.insert(vec[i]);
            result.push_back(vec[i]);
        }
    }
    return result;
}

9.数组al[0,mid-1]al[mid,n-1]是各自有序的,对数组al[0,n-1]的两个子有序段进行merge,得到al[0,n-1]整体有序。要求空间复杂度为O(1)。

void merge(int *a,int mid,int n)
{
    int i=0,j=mid;
    while(i<j&&j<n)
    {
        if(a[i]<=a[j])++i;
        else
        {
            int tmp=a[j];
            for(int k=j;k>i;--k)a[k]=a[k-1];
            a[i++]=tmp;
            ++j;
        }
    }
}

10.一个数组,含有重复元素,给出两个数num1和num2,求这两个数字在数组中出现的位置的最小距离。O(n)时间复杂度,O(1)空间复杂度。

int f(int *a,int n,int num1,int num2)
{
	int index1=-1,index2=-1,res=INT_MAX;
	for(int i=0;i<n;++i)
	{
		if(a[i]==num1)
		{
			index1=i;
			if(index2>=0)res=min(res,index1-index2);
		}
		if(a[i]==num2)
		{
			index2=i;
			if(index1>=0)res=min(res,index2-index1);
		}
	}
	return res;
}

11.求解500万以内的亲和数

#include<iostream>  
using namespace std;  

int main()  
{
    int *sum=new int[5000001];
    int i,j;
    for(i=2;i<=5000000;++i)sum[i]=1;
    for(i=2;i<=2500000;++i)
    {
        j=2*i;
        while(j<=5000000)
        {
            sum[j]+=i;
            j+=i;
        }
    }
    for(i=2;i<=5000000;++i)
    {
        if(sum[i]<i&&sum[sum[i]]==i)cout<<sum[i]<<' '<<i<<endl;
    }
    delete sum;
    return 0;  
}  

12.去哪儿网2015春季校招笔试题

vector<vector<int> > merge(vector<vector<int> > dataRangePrices)
{
	vector<vector<int> > result;
	sort(dataRangePrices.begin(),dataRangePrices.end());
	result.push_back(dataRangePrices[0]);
	int m=dataRangePrices.size();
	for(int i=1;i<m;++i)
	{
		if(dataRangePrices[i][0]>result[result.size()-1][1])result.push_back(dataRangePrices[i]);
		else if(dataRangePrices[i][1]<result[result.size()-1][1])
		{
			if(dataRangePrices[i][2]!=result[result.size()-1][2])
			{
				int b=result[result.size()-1][1];
				int c=result[result.size()-1][2];
				result[result.size()-1][1]=dataRangePrices[i][0]-1;
				result.push_back(dataRangePrices[i]);
				int a[3]={dataRangePrices[i][1]+1,b,c};
				result.push_back(vector<int>(a,a+3));
			}
		}
		else 
		{
			if(dataRangePrices[i][2]==result[result.size()-1][2])result[result.size()-1][1]=dataRangePrices[i][1];
			else 
			{
				result[result.size()-1][1]=dataRangePrices[i][0]-1;
				result.push_back(dataRangePrices[i]);
			}
		}
	}
	return result;
}
vector<vector<int> > merge(vector<vector<int> > ranges)
{
	vector<vector<int> > result;
	sort(ranges.begin(),ranges.end());
	result.push_back(ranges[0]);
	int m=ranges.size();
	for(int i=1;i<m;++i)
	{
		if(ranges[i][0]>result[result.size()-1][1])result.push_back(ranges[i]);
		else if(ranges[i][1]>result[result.size()-1][1])result[result.size()-1][1]=ranges[i][1];
	}
	return result;
}

13.数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置。如数组:[1,2,3,4,3,4,5,6,5],找到4在数组中的位置。

vector<int> search(vector<int> vec,int x)
{
	vector<int> result;
	int i=(vec[0]-x)&1?1:0;
	while(i<vec.size())
	{
		if(vec[i]==x)result.push_back(i);
		i+=max(abs(vec[i]-x),2);
	}
	return result;
}

14.随机洗牌算法

void swap(int &x,int &y)
{
	int tmp=x;
	x=y;
	y=tmp;
}

void f(int a[],int n)
{
	srand((unsigned)time(0));
	for(int i=0;i<n;++i)
	{
		swap(a[i],a[i+rand()%(n-i)]);
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值