• 程序员面试金典


    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
  • 相关阅读:
    简易基础版单页面应用
    nginx服务器部署
    vim基础命令
    jsdoc — js注释
    eslint — js书写规范
    stylelint — css书写规范
    gulpfile.js(编译sass,压缩图片,自动刷新浏览器)
    gulp安装使用
    git常用命令
    generator-ivweb 基于react-redux的多页脚手架
  • 原文地址:https://www.cnblogs.com/jason1990/p/4725245.html
Copyright © 2020-2023  润新知