程序员面试金典

1.有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶、3阶。请实现一个方法,计算小孩有多少种上楼的方式。为了防止溢出,请将结果Mod 1000000007

给定一个正整数int n,请返回一个数,代表上楼的方式数。保证n小于等于100000。

int countWays(int n) {
        // write code here
        
        if(n<=0) return 0;
        else if(1==n) return 1;
        else if(2==n) return 2;
        else if(3==n) return 4;
            
        long long i,n1=1,n2=2,n3=4,n4;
        for(i=4;i<=n;i++){
            n4=((n1+n2)%1000000007+n3)%1000000007;
            n1=n2%1000000007;
            n2=n3%1000000007;
            n3=n4%1000000007;
        }
        return n4;
    }

中间计算结果会溢出,故如此处理。。。

 

2.编写一个函数,确定需要改变几个位,才能将整数A转变成整数B。

给定两个整数int A,int B。请返回需要改变的数位个数。

int calcCost(int A, int B) {
        // write code here
        
        int i=0,x=A^B;
        while(x){
            ++i;
            x=x&(x-1);
        }
        return i;
    }

 

3.从尾到头打印链表

输入一个链表,从尾到头打印链表每个节点的值。

vector<int> printListFromTailToHead(struct ListNode* head) {
        stack<int> value;
        vector<int> res;
        
        if(NULL==head) return res;
        else if(head->next==NULL){
            res.push_back(head->val);
            return res;
        }
        
        struct ListNode* temp=head;
        while(temp){
            value.push(temp->val);
            temp=temp->next;
        }
        
        int val;
        while(value.size()>0){
            val=value.top();
            value.pop();
            res.push_back(val);
        }
        
        return res;
    }

 

4.奇偶位交换

请编写程序交换一个数的二进制的奇数位和偶数位。(使用越少的指令越好)

给定一个int x,请返回交换后的数int。

 int exchangeOddEven(int x) {
        // write code here
        
        //奇数位右移,0xaaaa aaaa=10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010b; 
        int odd=(x&0xaaaaaaaa)>>1;  
         //偶数位左移,0x5555 5555=01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101b;
        int eve=(x&0x55555555)<<1;
        return odd|eve;
    }

简直了,不能再巧妙了。

 

5.实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。

给定带删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true

bool removeNode(ListNode* pNode) {
        // write code here
        
        if(NULL==pNode) return false;
        else if(pNode->next==NULL){
            return false;
        }else{
            pNode->val=pNode->next->val;
            pNode->next=pNode->next->next;
            return true;
        }
    }

 

6.有序数组合并

有两个从小到大排序以后的数组A和B,其中A的末端有足够的缓冲空容纳B。请编写一个方法,将B合并入A并排序。

给定两个有序int数组AB,A中的缓冲空用0填充,同时给定A和B的真实大小int n和int m,请返回合并后的数组。

(此题的鲁棒性不行,未做特例判断,后续添加)

class Merge {
public:
    vector<int> mergeAB(vector<int> A, vector<int> B, int n, int m) {
        // write code here
        
        int i=n-1,j=m-1,k=n+m-1;
        
        while(i>=0&&j>=0){
            if(A[i]>B[j]){
                A[k]=A[i];
                --k;--i;
            }else if(A[i]<B[j]){
                A[k]=B[j];
                --k;--j;
            }else{
                A[k]=A[i];
                --k;--i;
                A[k]=B[j];
                --k;--j;
            }
        }
        
        if(i>=0){
            for(i;i>=0;--i,--k){
                A[k]=A[i];
            }
        }else{
            for(j;j>=0;--j,--k){
                A[k]=B[j];
            }
        }
        
        return A;
    }
};

 

7.最大连续数列和

对于一个有正有负的整数数组,请找出总和最大的连续数列。

给定一个int数组A和数组大小n,请返回最大的连续数列的和。保证n的大小小于等于3000。

class MaxSum {
public:
    int getMaxSum(vector<int> A, int n) {
        // write code here
        
        int len=A.size();
        if(0==len){
            return 0;
        }else if(1==len){
            return A[0];
        } 
        
        int i,cursum=A[0],sum=A[0];
        for(i=1;i<len;i++){
            
            if(cursum<0){
                cursum=A[i];
            }else{
                cursum+=A[i];
            }
            
            if(sum<cursum){
                sum=cursum;
            }
        }
        
        return sum;
    }
};

 

8.阶乘尾零

class Factor {
public:
    int getFactorSuffixZero(int n) {
        // write code here
        
        int res=0;
        
        while(n){
            res+=n/5;
            n/=5;
        }
        
        return res;
    }
};

 

9.基本字符串压缩

利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。比如,字符串“aabcccccaaa”经压缩会变成“a2b1c5a3”。若压缩后的字符串没有变短,则返回原先的字符串。

给定一个string iniString为待压缩的串(长度小于等于3000),保证串内字符均由大小写英文字母组成,返回一个string,为所求的压缩后或未变化的串。

(原本想着偷懒,调用库函数实现整数转换为字符串,不过发现那似乎是CString的专利,string如此很麻烦,还是造了一个简陋的轮子)

class Zipper {
public:
    string zipString(string iniString) {
        // write code here
        
        int i=0,n=1,len=iniString.length();
        char s=iniString[0];
        string str(" "),num;
        str[0]=s;
        
        for(i=1;i<len;i++){
            
            if(iniString[i]==s){
                ++n;
            }else{ 
                str+=num2str(n);
                str+=iniString[i];
                
                //重新初始化
                s=iniString[i]; n=1;
            }
        }
        str+=num2str(n);
        
        if(str.length()<len){
            return str;
        }else{
            return iniString;
        }
    }
    
private:
    //此处num必然大于等于1,为避免外界调用,设置为私有格式
    //num=0时需特殊对待,负数的话可以考虑传递进来的时候传入一个负数标志
    string num2str(int num) {
       
       int i = 0, n = 0;
       string s1, s2;

       while (num) {    
           n = num % 10;
           num = num / 10;
           s1 += '0' + n;
       }
       
       for (i = s1.length()-1;i >= 0;--i) {    
           s2 += s1[i];
       }
       return s2;
    }
};

 

10.二叉平衡树检查

注意这里面的运算优先级。。。三目运算符的优先级较低

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

class Balance {
public:
    bool isBalance(TreeNode* root) {
        // write code here
        
        int depth=0;
        if(NULL==root)
            return true;
        else return BalaceDepth(root,depth);
    }
    
    bool BalaceDepth(TreeNode* root,int& depth){
        
        if(NULL==root){
            depth=0;return true;
        }
        
        int left=0,right=0,diff;
        if(BalaceDepth(root->left,left)&&BalaceDepth(root->right,right)){
            diff=left-right;
            if(diff<=1&&diff>=-1){
                //三目运算符的优先级较低,如果不添加括号,会先执行+left
                depth=1+(left>right?left:right);
                return true;
            }
            return false;
        }
        return false;
    }
};
View Code

 

posted @ 2015-08-12 18:27  从此寂静无声  阅读(510)  评论(0编辑  收藏  举报