zoukankan      html  css  js  c++  java
  • [微软面试100题]8190

    第八十一题:

    1、求数组中大于左边所有元素,小于右边素有元素的数。只能用一个额外数组。

    思路:从左往右遍历先把max记录在额外数组中。从右往左遍历记录当前min在一个变量中。对比min和max和当前即可。

    //复杂度O(n),2次迭代,使用1个数组
    void helper(int *a,int n){
        int nowmax=a[0],nowmin=a[n-1];
        int max[n];
        for(int i=0;i<n;++i){
            if(a[i]>nowmax)nowmax=a[i];
            max[i]=nowmax;
        }
        for(int i=n-1;i>=0;--i){
            if(a[i]<nowmin)nowmin=a[i];
            if(a[i]>=max[i] && a[i]<=nowmin)cout<<a[i]<<endl;
        }
    }

    2、一千万条字符串,找出所有系相反的字符串。

    思路:先hash所有字符串,然后一条一条翻转再hash,冲突则输出即可。

    第八十二题:

    1、用C++模拟类似SQL的存储以及查询功能

    class col
    {
    public:
        string name;
        int age;
        int index;
        static int nowindex;
        col(string name,int age);
    };
    int col::nowindex=0;//静态成员类外初始化
    class table
    {
        vector<col> cols;//用序号对vector随机存取
        map<string,int> name2index;//用一个hashtable关联名字和序号
    public:
        void insert(string name,int age);
        int find_age(string name);
        void find_name(char c,int age);
    };
    col::col(string name,int age){
        index=nowindex;
        nowindex++;
        this->name=name;
        this->age=age;
    }
    void table::insert(string name,int age){
        col tmp(name,age);
        cols.push_back(tmp);
        name2index[name]=tmp.index;
    }
    int table::find_age(string name){
        if(name2index.find(name)!=name2index.end()){//判断map元素是否存在方法
        int index=name2index[name];
        return cols[index].age;
        }
        return -1;
    }
    void table::find_name(char c,int age){
        int len=cols.size();
        bool has_result=false;
        if(c=='='){
            for(int i=0;i<len;++i)
                if(cols[i].age==age){
                    has_result=true;
                    cout<<cols[i].name<<endl;
                }
        }else if(c=='>'){
            for(int i=0;i<len;++i)
                if(cols[i].age>age){
                    has_result=true;
                    cout<<cols[i].name<<endl;
                }
        }else if(c=='<'){
            for(int i=0;i<len;++i)
                if(cols[i].age<age){
                    has_result=true;
                    cout<<cols[i].name<<endl;
                }
        }else cout<<"error"<<endl;
        if(!has_result)cout<<"not found"<<endl;
    }

     2、100亿条记录,包括两个字段{URL,SIZE},用shell抓取出包含baidu的size,并根据size排名

    shell以后再复习。。。忘记了。。

    思路:如果是C++的话,先找出含有baidu的,然后用堆排序。

    第八十三题:实现memcpy函数

    PS:注意区间重叠的情况即可

    void* memmove(void* dest,const void* src,size_t n){
        if(dest==NULL || src==NULL)return NULL;
        char* byte_src=(char*)src;
        char* byte_dest=(char*)dest;
        int step=1;
        if((size_t)dest<(size_t)src+n){//防止原内存区间与目标区间重叠
            byte_src+=n-1;
            byte_dest+=n-1;
            step=-1;
        }//目标区间比原区间后,则需从最后开始复制
        //虽然重叠但目标在原区间前,则不会冲突
        for(size_t i=0;i<n;++i){
            *byte_dest=*byte_src;
            byte_dest+=step;
            byte_src+=step;
        }
        return dest;
    }

     第八十四题:

    1、用最快的方法找出相同的字符串

    思路:(1)hash(2)字典树

    2、字符串中子串的个数

    思路:(1)从左往右扫不断对比,复杂度O(mn);(2)从左往右的hash,复杂度O(m)

    第八十六题:二叉树存放有序数组

    思路:死记硬背不好,只要那个1到7的数组写出它的前序、中序、后序遍历二叉树就知道程序怎么写了。

    //前序遍历顺序。根节点是第一个元素,后面的元素分开两半,分别递归即可。
    void BinaryTreeNode::buildfirst(int *a,int n){
        this->m_nValue=a[0];
        int lenleft=(n-1)/2;
        if(lenleft>0){
            this->m_pLeft=new BinaryTreeNode;
            this->m_pLeft->buildfirst(a+1,lenleft);
        }
        if(n-1-lenleft>0){
            this->m_pRight=new BinaryTreeNode;
            this->m_pRight->buildmid(a+1+lenleft,n-lenleft-1);
        }
    }
    //中序遍历顺序。根节点是中间元素,前后两段元素分别递归即可。
    void BinaryTreeNode::buildmid(int *a,int n){
        int mid=n/2;
        this->m_nValue=a[mid];
        if(mid>0){
            this->m_pLeft=new BinaryTreeNode;
            this->m_pLeft->buildmid(a,mid);
        }
        if(n-mid-1>0){
            this->m_pRight=new BinaryTreeNode;
            this->m_pRight->buildmid(a+mid+1,n-mid-1);
        }
    }
    //后序遍历顺序。根节点是最后一个元素,前面的元素分开两半,分别递归即可。
    void BinaryTreeNode::buildlast(int *a,int n){
        this->m_nValue=a[n-1];
        int lenleft=(n-1)/2;
        if(lenleft>0){
            this->m_pLeft=new BinaryTreeNode;
            this->m_pLeft->buildlast(a,lenleft);
        }
        if(n-1-lenleft>0){
            this->m_pRight=new BinaryTreeNode;
            this->m_pRight->buildlast(a+lenleft,n-lenleft-1);
        }
    }

     第八十七题:大数相乘

    思路:用字符串逐位相乘,累加到结果的数组中。最后处理结果数组考虑进位。

    string muti(string s1,string s2){
        int len1=s1.length(),len2=s2.length();
        int *i1=new int[len1];
        int *i2=new int[len2];
        int *result=new int[len2+len1];
        memset(result,0,(len1+len2)*sizeof(int));
        for(int i=0;i<len1;++i)
            i1[i]=s1[len1-i-1]-'0';
        for(int i=0;i<len2;++i)
            i2[i]=s2[len2-i-1]-'0';
    
        for(int i=0;i<len1;i++){
            for(int j=0;j<len2;j++)
                result[i+j]+=i1[i]*i2[j];
        }
        for(int i=0;i<len1+len2;++i){
            if(result[i]>9){
                result[i+1]+=result[i]/10;
                result[i]=result[i]%10;
            }
        }
        string str;
        bool flag=true;
        for(int i=len1+len2-1;i>=0;--i){
            if(flag && result[i]==0)continue;
            flag=false;
            str+=result[i]+'0';
        }
        delete [] i1;
        delete [] i2;
        delete [] result;
        return str;
    }

     大数相加:

    string add(string s1,string s2){
        int len1=s1.length(),len2=s2.length();
        int *i1=new int[len1];
        int *i2=new int[len2];
        int len3=len1>len2?len1+1:len2+1;
        int *result=new int[len3];
        memset(result,0,len3*sizeof(int));
        for(int i=0;i<len1;++i)
            i1[i]=s1[len1-i-1]-'0';
        for(int i=0;i<len2;++i)
            i2[i]=s2[len2-i-1]-'0';
    
        for(int i=0;i<len3-1;i++){
            if(len1<len2 && i>=len1)
                result[i]=i2[i];
            else if(len2<len1 && i>=len2)
                result[i]=i1[i];
            else result[i]=i1[i]+i2[i];
        }for(int i=0;i<len3;++i){
            if(result[i]>9){
                result[i+1]+=result[i]/10;
                result[i]=result[i]%10;
            }
        }
      string str; bool flag=true; for(int i=len3-1;i>=0;--i){ if(flag && result[i]==0)continue; flag=false; str+=result[i]+'0'; } delete [] i1; delete [] i2; delete [] result; return str; }

     第八十八题:把*移到字符串前部

    思路:记录两个坐标,一个是最后一个星,一个是最后一个字母。从后往前扫,扫到字母就与最后一个星交换。

    int helper(char *s){
        int len=strlen(s);
        int i=len-1,j=len-1,count=0;
        while(j>=0){//j往前扫,直到不是*,i的位置一定是最后一个*
            if(s[j]!='*'){
                swap(s,i--,j--);//交换了以后,i-1肯定是*
                //如2个*连续则交换后显然是*;只有1个*的话,下一个就是刚交换的*
            }else{
                count++;
                j--;
            }
        }
        return count;
    }

     第八十九题:删除字符串中的数字

    思路:与上题基本一致。while循环一次做cursor移动一步,不要再用while,否则代码不简洁。

    bool is_digit(char c){
        return (c>='0' && c<='9')?true:false;
    }
    char* helper(char *s){
        int i=0,j=0;
        while(s[j]!='\0'){
            if(!is_digit(s[j]))s[i++]=s[j++];
            else j++;
        }
        s[i]='\0';
        return s;

     第九十题:不使用临时空间翻转字符串

    //模拟一个栈,如果只是翻转输出的话
    void helper(char *s,int i,int n){
        if(i<n-1){
            helper(s,i+1,n);//没到最后,先递归
            cout<<s[i]<<endl;//递归完说明此元素之后的元素已经处理完毕,可处理此元素了
        }
        else cout<<s[i]<<endl;//最后的元素,停止递归
    }
    
    void helper2(char *s,int n){
        int i=0,j=n-1;
        while(j>i){
            char tmp=s[i];
            s[i]=s[j];
            s[j]=tmp;
            ++i;
            --j;
        }
    }
    //如何真的连一个char都不能申请只能使用
    //想起一种不借助临时变量交换变量的方法
    void helper3(char *s,int n){
        int i=0,j=n-1;
        while(j>i){
            s[i]^=s[j];//左包含ij的与或
            s[j]^=s[i];//右包含jij=i
            s[i++]^=s[j--];//左包含iji=j
        }
    }
  • 相关阅读:
    mySQL部分疑问和小结(orale)
    Java技术中的三大特性
    Java调用DB的存储过程
    Android Http异步请求,Callback
    android Handler的使用(一)
    Android之ContextMenu的使用方法以及与OptionMenu的区别(转)
    git 把文件从 版本管理中移除 andorid版本
    在GIT 中增加忽略文件夹与文件
    玩转Android---组件篇---Intent(意图)
    Android Activity和Intent机制学习笔记
  • 原文地址:https://www.cnblogs.com/iyjhabc/p/2988470.html
Copyright © 2011-2022 走看看