【C++後臺開發面經】面試總結第四波:筆試面試算法題總結

前言

        面試總結第四波,主要針對面試時要求編寫的算法編程題總結。

C++面試筆試算法題合集

1、之字形打印二叉樹

vector<vector<int>> print(TreeNode *node){
    vector<vector<int>> res;
    if(!node) return res;
    queue<TreeNode*> q;
    q.push(node);
    int flag=false;
    
    while(q.size()){
        int len=q.size();
        vector<int> line;
        for(int i=0;i<len;i++){
            auto p=q.front();
            line.push_back(p->val);
            if(p->left) q.push(p->left);
            if(p->right) q.push(p->right);
            q.pop();
        }
        if(flag){
            reverse(line.begin(),line.end());
        }
        flag=!flag;
        res.push_back(line);
    }
}

2、K路歸併有序鏈表

ListNode* mergeKList(vector<ListNode*> &lists){
    
    priority_queue<pair<int,ListNode*>,vector<pair<int,ListNode*>>,greater<pair<int,ListNode*>>> pq;
    
    for(auto p:lists){
        if(p) pq.push({p->val,p});
    }
    
    auto pre=new ListNode(-1);
    auto cur=pre;
    while(pq.size()){
        auto t=pq.top();
        if(t.second->next) pq.push({t.second->next->val,t.second->next});
        cur->next=t.second;
        cur=cur->next;
        pq.pop();
    }
    return pre->next;
}

3、簡單實現一個LRU

class LRUCache{
private:
    int n;
    list<pair<int,int>> l;
    unordered_map<int,list<pair<int,int>>::iterator> hash;
public:
    LRUCache(int capacity){
        n=capacity;
    }
    
    int get(int key){
        int ret=-1;
        auto iter=hash.find(key);
        if(iter!=hash.end()){
            auto temp=hash[key];
            ret=temp->second;
            l.erase(temp);
            l.push_front({key,ret});
            hash[key]=l.begin();
        }
        return ret;
    }
    
    void put(int key,int value){
        auto iter=hash.find(key);
        if(iter!=hash.end()){//緩存中有此數據,先刪掉
            l.erase(iter->second);
        }
        else if(l.size()<n){
            
        }
        else{
            int key=l.back().first;//緩存中沒有此數據,且已超過n,刪除鏈表最後值
            l.pop_back();
            hash.erase(key);
        }
        l.push_front({key,value});//把新數據放到鏈表首
        hash[key]=l.begin();
    }
};

4、正則字符匹配(?和*)

bool isMatch(string &s,string &p){
    int n=s.size(),m=p.size();
    vector<vector<bool>> f(n+1,vector<bool>(m+1));
    
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            
            if(!i&&!j){//空串匹配空串
                f[i][j]=true;
                continue;
            }
            if(!j){ //正則表達式爲空
                f[i][j]=false;
                continue;
            }
            if(p[j-1]!='*'){
                if(i>0&&(p[j-1]=='?'||s[i-1]==p[j-1])) f[i][j]=f[i][j]||f[i-1][j-1];
            }
            else{
                f[i][j]=f[i][j]||f[i][j-1]; //忽略
                if(i>0) f[i][j]=f[i][j]||f[i-1][j];  //不忽略
            }
        }
    }
    
    return f[n][m];
}

5、單次買賣股票最大利潤

6、二叉樹非遞歸後序遍歷

7、循環隊列

8、刪除一個平衡二叉樹的非葉子節點

9、KMP算法

10、超大數組去重,排序

11、編寫一個撲克牌洗牌程序

12、快速排序非遞歸

void quick_sort(vector<int> &q){
    int n=q.size();
    stack<int> s;
    int top=0;
    int i,j,high,low,provit;
    s.push(n-1);  //high
    s.push(0);   //low
    while(s.size()){
        low=s.top(),s.pop();  //把右端點壓入棧中
        high=s.top(),s.pop();  //把左端點壓入棧中
        provit=high;   //選中右端點爲中心軸
        i=low;     
        for(j=low;j<high;j++){ //遍歷,把小於的部分放在前面
            if(q[j]<=q[provit]){
                swap(q[j],q[i++]);
            }
        }
        if(i!=provit){ //交換中心軸
            swap(q[i],q[provit]);
        }
        if(i-low>1){ //若前半部分個數大於1個,則入棧
            s.push(i-1);
            s.push(low);
        }
        if(high-i>1){ //若後半部分個數大於1個,則入棧
            s.push(high);
            s.push(i+1);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章