zoukankan      html  css  js  c++  java
  • 剑指offer习题集

    1.重载赋值运算符函数:(具体见代码)

    //普通做法
    CMyString& CMyString::operator=(const CMyString& str)
    {
        if (this == &str) 
            return *this;
    
        delete[] m_Pdata;
        m_Pdata = new char[strlen(str.m_Pdata)+1];
        strcpy(m_Pdata,str.m_Pdata);
    
        return *this;
    }
    
    //更加安全的做法,普通做法在new内存不足情况下,已经将原值delete
    CMyString& CMyString::operator=(const CMyString& str)
    {
        if (this != &str)
        {
            CMyString strTemp(str);
    
            char* temp = str.m_Pdata;
            //通过strTemp的析构函数delete掉原值
            strTemp.m_Pdata = m_Pdata; 
            m_Pdata = temp; 
        }
    
        return *this;
    }

    2.替换字符串中的空白字符

    瞎了,做了一遍结果还是出错。。。确实要多练练

    class Solution {
    public:
        //length为数组容量
        void replaceSpace(char *str,int length) {
            
            if(length<=0||str==NULL) return;
            
            int i=0,n_blank=0,n_str=0,n_strlength=0;
            while(str[i]!=''){
                ++n_str;
               
                if(' '==str[i])
                    ++n_blank;
                
                ++i;
            }
            
            n_strlength=n_str+n_blank*2;
            if(n_strlength>length) return;
            
            int n1=n_str,n2=n_strlength;
            while(n1>=0&&n2>n1){
                if(str[n1]==' '){
                    str[n2--]='0';
                    str[n2--]='2';
                    str[n2--]='%';
                }else{
                    str[n2--]=str[n1];
                }
                
                --n1;
            }  
        }
    };

    3.使用两个栈模仿队列

    class Solution
    {
    public:
        void push(int node) {
            stack1.push(node);
        }
    
        int pop() {
            int temp;
            
            if(stack2.size()<=0){
                while(stack1.size()>0){
                    temp=stack1.top();
                    stack2.push(temp);
                    stack1.pop();
                }
            }
            
            if(stack2.size()<=0) 
                return 0;
            
            temp=stack2.top();
            stack2.pop();
            return temp;
        }
    
    private:
        stack<int> stack1;
        stack<int> stack2;
    };

    4.改进的斐波那契数列

    class Solution {
    public:
        int Fibonacci(int n) {
            
            if(n<=0) return 0;
            
            if(1==n||2==n) return 1;
            
            long long n1=1,n2=1,n3=0;
            for(int i=2;i<n;i++){
                n3=n1+n2;
                n1=n2;
                n2=n3;
            } 
            return n3;
        }
    };

    5.实数的整数次方

    class Solution {
    public:
        double Power(double base, int exponent) {
            
            //防止0作为底数
            if(equal(base,0.0)){
                if(0==exponent) return 1.0;
                else return 0.0;
            } 
            
            //针对0次方做的特殊处理
            if(0==exponent) return 1.0;
            else if(1==exponent) return base;
            
            double res;
            bool sign=exponent<0?true:false;
            
            if(sign){
                return 1.0/PowerD(base,-1*exponent);
            }else{
                return PowerD(base,exponent);
            }
        }
        
        bool equal(const double &a,const double &b){
            if(fabs(a-b)<1e-6)
                return true;
            return false;
        }
        
        double PowerD(double base,int exponent){
            
            if(1==exponent) return base;
            else if(0==exponent) return 1.0;
           
            double res=PowerD(base,exponent/2);
            res*=res;
            if(exponent&0x01==1){ //判断是否是奇数次方
                res*=base;
            }
            return res;
        }
    };

    6.求链表的倒数第k个节点

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            
            if(NULL==pListHead||k==0) return NULL;
            
            int i=k;
            ListNode *t1=pListHead,*t2=pListHead;
            
            while(i!=0&&t1!=NULL){
                --i;
                t1=t1->next;
            }
            
            if(i!=0) return NULL;
            
            while(t1!=NULL){
                t1=t1->next;
                t2=t2->next;
            }
            return t2;
        }
    };

    7.包含min函数的栈

    class Solution {
    public:
        void push(int value) {
            
            m_data.push(value);
            
            if(m_min.size()==0){
                m_min.push(value);
            }else{
                if(value<m_min.top())
                    m_min.push(value);
                else m_min.push(m_min.top());
            }
        }
        void pop() {
            if(m_data.size()>0){
                m_data.pop();
                m_min.pop();
            }
        }
        int top() {
            if(m_data.size()>0)
                return m_data.top();
        }
        int min() {
            if(m_min.size()>0) 
                return m_min.top();
        }
        
    private:
        stack<int> m_data;
        stack<int> m_min;
    };

    8.给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。

    vector<int> multiply(const vector<int>& A) {
            
            int i,len=A.size(),temp=1;
            vector<int> res;
            if(len<=1) return res;
            
            res.push_back(1);
            for(i=1;i<len;i++){
                res.push_back(res[i-1]*A[i-1]);
            }
            
            for(i=len-2;i>=0;i--){
                temp*=A[i+1];
                res[i]*=temp;
            }
            
            return res;
        }

    此题没怎么注意代码的鲁棒性,后续可以补充。

    9.一个链表中包含环,请找出该链表的环的入口结点。

    ListNode* EntryNodeOfLoop(ListNode* pHead)
        {
            if(pHead==NULL) return NULL;
             
            //找到环中节点
            ListNode *p1=MeetListNode(pHead),*p2;
            if(p1==NULL) return NULL;
             
            //计算链表中环的节点个数
            int i,n=1;
            p2=p1->next;
            while(p2!=p1){
                ++n;
                p2=p2->next;
            }
             
            //寻找链表中环的入口节点
            p1=pHead;p2=pHead;
            for(i=0;i<n;i++){
                p1=p1->next;
            }
            while(p1!=p2){
                p1=p1->next;
                p2=p2->next;
            }
            return p1;
        }
         
        ListNode* MeetListNode(ListNode* pHead){
             
            ListNode *p1=pHead->next,*p2=pHead;
            if(pHead==NULL||p1==NULL||p1->next==NULL) return NULL;
             
            p1=p1->next;
            while(p1!=p2){
                 
                p2=p2->next;
                 
                p1=p1->next;
                if(p1->next==NULL){
                    return NULL;
                }else{
                    p1=p1->next;
                }
            }
            return p1;
        }

    这道题有更加快捷优化的做法,后续做更新。这里只是将书本上的思路进行阐述。

    10.在一个长度为n的数组里的所有数字都在0到n-1的范围内。

    数组中某些数字是重复的,但不知道有几个数字是重复的。

    也不知道每个数字重复几次。请找出数组中任意一个重复的数字。

    例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

    bool duplicate(int numbers[], int length, int* duplication) {
            
            if(NULL==numbers||length<=1) return NULL;
            
            int i,temp;
            for(i=0;i<length;i++){ //对数据的正确性进行检测
                if(numbers[i]<0||numbers[i]>length-1)
                    return NULL;
            }
            
            for(i=0;i<length;i++){
                while(numbers[i]!=i){
                    if(numbers[i]==numbers[numbers[i]]){
                        *duplication=numbers[i];
                        return true;
                    }
                    
                    //进行数值交换
                    temp=numbers[i];
                    numbers[i]=numbers[temp];
                    numbers[temp]=temp;
                }  
            }
            
            return false;
        }

    这道题还是比较绕,不能熟练掌握。

    11.第一个只出现一次的字符

    此题其实比较简单,但是要知道ASCII码共有256个。其实不知道也无妨,将hashtable设置较大即可。

    期望于一个循环解决问题,是可以的,但是在面试的过程中,最重要的是解决题目,进而进行优化。

    class Solution {
    public:
        int FirstNotRepeatingChar(string str) {
            
            int len=str.length();
            if(0==len) 
                return -1;
            else if(1==len){
                return 0;
            }
            
            const int size=256;
            unsigned int i,hashtable[size]={0};
            
            for(i=0;i<len;++i){
                ++hashtable[str[i]];
            }
            
            for(i=0;i<len;++i){
                if(1==hashtable[str[i]])
                    return i;
            }
            
            return -1;
        }
    };

    12.数组中只出现一次的数字

    此题可以扩展范围,比如字符之类的,总之方法如果不是看书,蛮难想到的

    class Solution {
    public:
        void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
            
            int len=data.size();
            if(len<2) 
                return;
            else if(2==len&&data[0]!=data[1]){
                *num1=data[0];
                *num2=data[1];
                return;
            }
            
            int i,n=0,temp=data[0],res;
            for(i=1;i<len;i++){
                temp=temp^data[i];
            }
            
            //寻找二进制中初始为1数字
            while(!(temp&0x01)&&(n<8*sizeof(int))){
                ++n;
                temp=temp>>1;
            }
            
            *num1=0;*num2=0;
            for(i=0;i<len;++i){
                
                res=(data[i]>>n)&0x01;
                
                if(res){
                    *num1^=data[i];
                }else{
                    *num2^=data[i];
                }
            }
            
            return;
        }
    };
  • 相关阅读:
    oracle常用sql语句
    Oracle存储过程基本语法介绍
    优美的代码:do...while(0)
    半同步半异步线程池
    C11线程管理:异步操作
    C11线程管理:原子变量&单调函数
    C11线程管理:条件变量
    C11线程管理:互斥锁
    C11线程管理:线程创建
    C11关键字&字面值改善
  • 原文地址:https://www.cnblogs.com/jason1990/p/4694821.html
Copyright © 2011-2022 走看看