[微软面试100题]7180

第七十一题:求a的b次方
思路1:循环乘积
思路2:half=a^(b/2) 即a^b=half*half,复杂度从O(n)降为O(logn)
PS:除以二可以用>>1代替,判断可以否整除2可以用 & 1代替,位操作提高系效率。
double helper(double base,int power){
    if(power==1)return base;
    if(power==-1)return 1/base;
    if(power%2==0){
        double half=helper(base,power/2);
        return half*half;
    }else{
        double half=helper(base,(power-1)/2);
        return half*half*base;
    }
}
 
double helper2(double base,int power){
    if(power==1)return base;
    if(power==-1)return 1/base;
    double half=helper(base,power/2);//可改进为power>>1右移一位
    return ((power%2==0)?1:base)*half*half;//可改进为power & 1==0表示末尾为0可以整除2
}
 第七十二题:单例设计
思路:用静态static变量记录实例个数,私有化构造函数。用static函数接口来调用构造函数
PS类中静态成员必须在类以外初始化
class single{
    static int count;//只声明没定义
    single(){}//必须要加大括号 不然没定义
public:
    static single* create(){
        if(single::count==0){
            single::count++;
            return new single;
        }else return NULL;
    }
    void del();
};
int single::count=0;//类中静态成员必须在类以外初始化,定义
 
第七十三题:求最长回文
思路:依次从后往前扫,复杂度O(n^2)。答案说可以用后缀树提高效率,最后还是没弄懂。
int helper(char *str){
    int len=strlen(str);
    int maxlen=0;
    for(int i=0;i<len;++i){
        int tmp=0;
        int head=i;
        for(int j=len-1;j>=head;--j){
            if(head==j){
                tmp++;
                head++;
            }
            else if(str[head]==str[j]){
                tmp+=2;
                head++;
            }
            else{
                tmp=0;
                head=i;
            }
        }
        if(tmp>maxlen)maxlen=tmp;
    }
    return maxlen;
}
第七十四题:数组中出现次数超过数组长度一半的数
思路:因为出现次数超过一半,因此只要把其他的数和那个数一起抵消掉,剩下的肯定就是所要找的数。因此扫描数组,遇上不同的就同时删除。其实不用真的删除数组中的数,只要用一个cnt记录当前数字的量,遇到不同的减一,遇到相同加一,cnt为0了就令下一个数字为当前数字。
int helper(int *num,int n){
    int cnt=0;
    int x;
    for(int i=0;i<n;++i){
        if(cnt==0){
            x=num[i];
            cnt++;
        }else if(num[i]==x)cnt++;
        else cnt--;
    }
    return x;
}

 第七十五题:二叉树最低公共父节点

思路:左右子树同时存在目标的话,就是该节点。因此使用递归查找子树是否存在目标,如果存在,利用返回值往上传。
BinaryTreeNode* helper(BinaryTreeNode *root,BinaryTreeNode *one,BinaryTreeNode *two){
    if(root==one|| root==two)return root;
    if(root==NULL)return NULL;
    BinaryTreeNode *left=helper(root->m_pLeft,one,two);
    BinaryTreeNode *right=helper(root->m_pRight,one,two);
    if(left!=NULL && right!=NULL)return root;
    else if(left==NULL && right==NULL)return NULL;
    else if(left!=NULL)return left;
    else return  right;
}

第七十六题:复制复杂链表

[微软面试100题]71-80 - "_艿譹┾ -
 
[微软面试100题]71-80 - "_艿譹┾ -
 
思路:1、新建节点,插在原节点后,如上图。2、建立新节点的偏移跳转。3、分离新旧链表
 
第七十九题:单链表排序
思路:由于单链表不能随机存取,用快排不方便,因此单链表最快的排序方法是归并排序。
PS:归并排序复杂度logN,而且是稳定排序(元素相对位置不改变)。核心思想是把两个有序数组合并。当递归到子数组长度为1时就已经有序了。
//合并两个有序数组
void merge(int *a,int m,int *b,int n,int *buf){
    int i,j,k;
    i=j=k=0;
    while(i<m && j<n){
        if(a[i]<b[j])buf[k++]=a[i++];
        else buf[k++]=b[j++];
    }
    while(i<m)buf[k++]=a[i++];
    while(j<n)buf[k++]=b[j++];
    //先合并到buf,再复制回原数组,避免重复新建空间
    for(int i=0;i<n+m;++i)a[i]=buf[i];
}

void mergesort(int *c,int n,int *buf){
    if(n==1)return;
    int *a=c,*b=c+n/2;
    int na=n/2,nb=n-n/2;
    mergesort(a,na,buf);
    mergesort(b,nb,buf);
    merge(a,na,b,nb,buf);//使用buf
}
void merge_sort(int *c,int n){
    int buf[n];
    mergesort(c,n,buf);
}
原文地址:https://www.cnblogs.com/iyjhabc/p/2985984.html