劍指offer(八)

36. 數組中出現次數超過一半的數字

自己想的是類似於桶排序的方法,時間複雜度雖然是O(n),但是是用的空間換時間,不划算。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int size=numbers.size();
        if(size<=0) return 0;
        if(size==1) return numbers[0];
        vector<int> temp(size,0);
        for(int i=0;i<size;i++){
            if(temp[numbers[i]]>=size/2)
                return numbers[i];
            temp[numbers[i]]++;
        }
        return 0;
    }
};

書上的方法。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int size=numbers.size();
        if(size<=0) return 0;
        if(size==1) return numbers[0];
        int result;
        int times=0;
        for(int i=0;i<size;i++){
            if(times==0){
                result=numbers[i];
                times++;
            }
            else if(result==numbers[i]) times++;
            else times--;
        }
        times=0;
        for(int i=0;i<size;i++){
            if(result==numbers[i]) times++;
        }
        if(times*2>size) return result;
        return 0;
    }
};

37. 最小的k個數

基本思路,時間複雜度O(nlog(n)),先排序再挑前k個

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> res;
        if(k>input.size()) return res;
        if(k==input.size()) return input;
        Quick(input,0,input.size()-1);
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
private:
    void Quick(vector<int>& input,int begin,int end){
        int pivot;
        if(begin<end){
            pivot= partition(input, begin, end); 
            Quick(input,begin,pivot-1);
            Quick(input,pivot+1,end);
        }  
    }
    int partition(vector<int>& input,int begin,int end){
        int mid=begin+(end-begin)/2;
        if(input[mid]>input[end]) swap(input,mid,end);
        if(input[begin]>input[end]) swap(input,begin,end);
        if(input[begin]<input[mid]) swap(input,begin,mid);
        int pivotkey=input[begin];
        while(begin<end){
            input[begin]=input[end];
            while(input[begin]<=pivotkey && begin<end) begin++;
            input[end]=input[begin];
            while(input[end]>pivotkey && begin<end) end--;
        }
        input[begin]=pivotkey;
        return begin;
        
    }
    void swap(vector<int>& input,int a,int b){
        int temp=input[a];
        input[a]=input[b];
        input[b]=temp;
    }
};

時間複雜度O(n),方法是類似快排的方法

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> res;
        if(k>input.size()) return res;
        if(k==input.size()) return input;
        int begin=0,end=input.size()-1;
        int pivot=partition(input,begin,end);
        while(pivot!=k-1 && begin<=end){
            if(pivot<k-1){
                begin=pivot+1;
                pivot=partition(input,begin,end);
            }
            else{
                end=pivot-1;
                pivot=partition(input,begin,end);
            }
        }
            
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
private:

    int partition(vector<int>& input,int low,int high){
        int begin=low;
        int end=high;
        if(input[begin]>input[end]) swap(input,begin,end);
        int pivotkey=input[begin];
        while(begin<end){
            input[begin]=input[end];
            while(input[begin]<=pivotkey && begin<end) begin++;
            input[end]=input[begin];
            while(input[end]>pivotkey && begin<end) end--;
        }
        input[begin]=pivotkey;
        return begin;
        
    }
    void swap(vector<int>& input,int a,int b){
        int temp=input[a];
        input[a]=input[b];
        input[b]=temp;
    }
};

38. 數據流中的中位數

書上的做法,詳情見備註,用的大頂堆與小頂堆的做法,時間複雜度O(logn)

class Solution {
public:
    void Insert(int num)
    {
        //小頂堆
        if((min.size()+max.size())&1){
            if(min.size()>0 && num>=min[0]){
                min.push_back(num);
                push_heap(min.begin(),min.end(),greater<int>());
                //將min中最小的元素插入到最大堆中,並刪除最小堆中的這個元素
                //這樣保證最大堆中的所有元素都比最小堆小。
                num=min[0];
                pop_heap(min.begin(),min.end(),greater<int>());
                min.pop_back();                  
            }

            max.push_back(num);
            push_heap(max.begin(),max.end(),less<int>());

        } 
        //大頂堆
        else{
            if(max.size()>0 && num<=max[0]){
                max.push_back(num);
                push_heap(max.begin(),max.end(),less<int>());
                //將max中最大的元素插入到最小堆中,並刪除最大堆中的這個元素
                //這樣保證最小堆中的所有元素都比最大堆大。
                num=max[0];
                pop_heap(max.begin(),max.end(),less<int>());
                max.pop_back();                
            }

            min.push_back(num);
            push_heap(min.begin(),min.end(),greater<int>());
        }
    }

    double GetMedian()
    { 
        int size=min.size()+max.size();
        if(size==0) return 0;
        double res;
        if(size&1) res = min[0];
        else res = (min[0]+max[0])/2.0;
        return res;
    }
private:
    vector<int> min;//小頂堆
    vector<int> max;//大頂堆
};

39. 連續數組的最大和

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        if(array.size()<=0) return 0;
        if(array.size()==1) return array[0];
        int sum=array[0];
        int max=array[0];
        for(int i=1;i<array.size();i++){
            if(sum<=0) sum=0;
            sum+=array[i];
            if(max<sum) max=sum;  
        }
        return max;
    }
};

40. 整數中1出現的次數(從1到n整數中1出現的次數)

純粹找規律找出來的。。

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        if(n<1) return 0;
        int res=0,temp=1,tempn=n;
        while(n/temp>0){
            if(tempn%10>1){
                res+=(tempn/10+1)*temp;
            }
            else if(tempn%10==1){
                res+=tempn/10*temp+n%temp+1;
            }
            else{
                res+=tempn/10*temp;
            }
            tempn/=10;
            temp*=10;
        }
        return res;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章