[心得]面试题分析与整理5

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值