剑指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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值