劍指offer題目1-10

面試題1 自定義字符串賦值運算符

//基本解法
CMyString& CMyString::operator=(const CMyString& str){
    if(this==&str)
        return *this;

    char* p = new char[strle(str.m_pData)+1]; //如果分配失敗,則不會改變原對象
    delete[] this.m_pData;
    m_pData = str.m_pData;
    strcpy(m_pData, str.m_pData);

    return *this;
}
//解法二
CMyString& CMyString::operator=(const CMyString& str){
    if(this != &str){
        CMyString strTemp(str);
        char* pTemp = strTemp.m_pData;
        strTemp.m_pData = m_pData;
        m_pData = pTemp;
    }

    return *this;
}

面試題2,C++實現單例模式

面試題3:二維數組中的查找

/* x 要查找的數
 * vec 二維數組
 * n 行數
 * m 列數
 * return true 或 false
 * 藉助vector實現
 */
bool Find1(int x, vector<vector<int> > vec, int n, int m){
    int i=0, j = m-1;
    while(i<=n-1 && j>=0){
        if(vec[i][j] == x)
            return true;
        else if(vec[i][j] > x)
            j--;
        else
            i++;
    }
    return false;
}
/*用一維數組實現二維數,空間需要是連續的
 */
bool Find2(int x, int a[], int n, int m){
    int i=0, j=m-1;
    while(i<=n-1 && j>=0){
        if(a[i*m+j] == x)
            return true;
        else if(a[i*m+j]>x)
            j--;
        else
            i++;
    }
    return false;
}

面試題4:替換空格, 把空格替換成%20

//從後往前移動
void Replace(char* str, int len){
    assert(str!=NULL && len>0); //len爲數組的容量大小
    int len1=0;//實際長度,字符串個數
    int i=0,len2=0,blank=0; //len2 替換後的長度
    while(str[i]!='\0'){
        if(str[i]==' ')
            blank++;
        i++;
    }
    len1 = i; // 最後str[i] = '\0', len1爲不包括最後‘\0’的字符個數
    len2 = len1 + blank*2;
    if(len2+1 > len) //至少需要len2+1個空間
        return;
    while(len1<len2){
        if(str[len1] == ' '){
            str[len2--] = '0';
            str[len2--] = '2';
            str[len2--] = '%';
        }
        else
            str[len2--] = str[len1];

        len1--;
    }
}

面試題5,從尾到頭打印鏈表

//藉助棧來實現
void rprint1(ListNode* head){
    stack<ListNode*> nodes;
    while(head){
        nodes.push(head);
        head = head->next;
    }

    while(!nodes.empty()){
        cout<<nodes.top()->value<<" ";
        nodes.pop();
    }
}
//遞歸,效率低下
void rprint2(ListNode* head)
{
    if(head==NULL)
        return;
    if(head->next != NULL){
        rprint(head->next);
    }
    printf("%d ", head->value);
}

面試題6,根據先序和中序遍歷重構二叉樹

TreeNode* construct(vector<int> pre, vector<int> in){
    int len = in.size();
    if(len==0)
        return NULL;

    vector<int> left_pre, left_in, right_pre, right_in;
    TreeNode* root = new TreeNode(pre[0]);

    int pos=0; // 需要初始化,跟節點在中序遍歷中的位置
    for(int i=0; i<len; i++){
        if(in[i]==pre[0]){
            pos = i;
            break;
        }
    }
    //左子樹的中序和先序遍歷
    for(int i=0; i<pos; i++){
        left_in.push_back(in[i]);
        left_pre.push_back(pre[i+1]);
    }
    //右子樹的中序和先序遍歷
    for(int i=pos+1; i<len; i++){
        right_in.push_back(in[i]);
        right_pre.push_back(pre[i]);
    }

    root->left = construct(left_pre,  left_in); //遞歸構造左子樹
    root->right = construct(right_pre, right_in);//遞歸構造右子樹
    return root;
}

面試題7,用兩個棧實現隊列

template<class T> class Queue{
public:
    Queue(){};
    ~Queue(){};
    bool empty(){ //判斷隊列是否爲空
        if(sta1.empty() && sta2.empty())
            return true;
        else
            return false;
    }
    void push(T value){ // 插入元素到隊列末尾
        sta2.push(value);
    }
    void pop(){ //刪除隊列元素
        if(empty())
            return;
        if(!sta1.empty())
            sta1.pop();
        else{
            while(!sta2.empty()){
                sta1.push(sta2.top());
                sta2.pop();
            }
            sta1.pop();
        }
    }
    T front(){ //返回隊列頭部元素
        assert(!empty());
        if(!sta1.empty()){
            return sta1.top();
        }else{
            while(!sta2.empty()){
            sta1.push(sta2.top());
            sta2.pop();
        }
            return sta1.top();
        }
    }
private:
    stack<T> sta1;
    stack<T> sta2;
};
//用兩個隊列實現一個棧
template<class T> class Stack{
public:
    bool empty(){
        if(q1.empty() && q2.empty())
            return true;
        else
            return false;
    }
    void pop(){
        if(empty())
            return;
        if(!q1.empty()){
            while(q1.size()>1){
                q2.push(q1.front());
                q1.pop();
            }
            q1.pop();
        }else{
            while(q2.size()>1){
                q1.push(q2.front());
                q2.pop();
            }
            q2.pop();
        }
    }
    void push(T value){
        if(!q1.empty()){ //如果q1不爲空,則放到q1中,
            q1.push(value);
        }else if(!q2.empty()){ //q1爲空,q2不爲空時放到q2中
            q2.push(value);
        }else{
            q1.push(value); //都爲空時,放到q1中
        }
    }
    T top(){
        assert(!empty());
            if(!q1.empty())
        return q1.back();
            else
        return q2.back();
    }
private:
    queue<T> q1;
    queue<T> q2;
};

面試題8,求旋轉數組中的最小數字

//順序查找
int FindMin(vector<int> a, int left, int right){
    int min = a[left];
    for(int i=left+1; i<=right; i++){
        if(a[i]<min)
            min = a[i];
    }
    return min;
}
//
int minNumberInRotateArray(vector<int> ra) {
    int len = ra.size();
    if(len==0)
        return 0;
    int left = 0;
    int right = len -1;
    int mid = 0; //若開始有序,則第一個數即爲所要求的數字,
    //即不會進入下面的循環
    while(ra[left]>=ra[right]){
        if(right-left == 1){ //相鄰
            mid = right;
            return ra[mid];
            //break; //直接return也可以
        }
        mid = (left+right)/2;
        //相同,無法判斷移動方向,則採用順序查找的方式
        if(ra[left] == ra[right] && ra[mid] == ra[left])
            return FindMin(ra, left, right);

        if(ra[mid]>=ra[left])       //mid在前面的遞增數列中
            left = mid;
        else if(ra[mid]<=ra[right]) //mid在後面的遞增數列中
            right = mid;
    }
    return ra[mid];
}

面試題9,斐波那契數列

//迭代,遞歸效率太低
//類似題目,青蛙跳臺階(變態跳臺階2的n-1次方),矩形拼圖,
long long fib(long long n){
    assert(n>=0);
    if( n<2 )
        return n;
    long long a = 0;
    long long b = 1;
    long long res=0;
    for(int i=2; i<=n; i++){
        res = a+b;
        a = b;
        b = res;
        cout<<"res="<<res<<endl;
    }
    return res;
}

面試題10, 求整數中1的個數

int numberOf1(int n){
    int count = 0;
    while(n){
        n &= n-1;
        count++;
    }
    return count;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章