劍指offer(十二)

56. 滑動窗口的最大值

這題我覺得最麻煩的是,size使用的 unsigned int的類型,導致後面有點麻煩,所以我直接轉成int型了。

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        string str=to_string(size);
        int s=atoi(str.c_str());
        if(num.size()<=0 || s<=0 || s>num.size()) return {};
        if(s==1) return num;
        vector<int> res;                
        int maxindex=0;
        for(int j=1;j<s && j<num.size();j++)
            maxindex=num[maxindex]>num[j]?maxindex:j;
        res.push_back(num[maxindex]);
        
        for(int i=s;i<num.size();i++){
            if(num[i]>=num[maxindex]){
                maxindex=i;
                res.push_back(num[maxindex]);
            }
            else{
                if(maxindex!=i-s)
                    res.push_back(num[maxindex]);
                else{
                    maxindex=i-s+1;
                    for(int j=i-s+2;j<=i;j++)
                        maxindex=num[maxindex]>num[j]?maxindex:j;
                    res.push_back(num[maxindex]);
                }
            }
        }
        return res;
    }
};

書上的思路,我寫的有點混亂。
思想是index.front()永遠是序列最大值
如果當前值比之前的最大值大,那麼清空index,存入當前的下標
如果當前值小,那麼比較當前值與index中末尾值的大小。若當前值大則刪去末尾值,直到末尾值大於當前值,插入當前值
當最大值即index的第一個位置的值已不在序列範圍內,刪除該值。

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        string str=to_string(size);
        int s=atoi(str.c_str());
        
        if(num.size()<=0 || s<=0 || s>num.size()) return {};
        if(s==1) return num;
        
        vector<int> res; 
        deque<int> index;
        index.push_back(0);
        
        for(int i=1;i<num.size();i++){
            if(index.front()<=i-s) index.pop_front();
            if(num[i]>=num[index.front()]){
                index.clear();
                index.push_back(i);
            }
            else{
                while(index.size()>0 && num[i]>num[index.back()])
                    index.pop_back();
                index.push_back(i);
            }
            if(i>=s-1)
                res.push_back(num[index.front()]);
        }
        return res;
    }
};

57. 撲克牌順子

自己的想法,先冒泡排序,再根據0的數量判斷順子是否成立。

class Solution {
public:
    void swap(vector<int> &numbers,int i,int j){
        int temp=numbers[i];
        numbers[i]=numbers[j];
        numbers[j]=temp;
    }
    bool IsContinuous( vector<int> numbers ) {
        if(numbers.size()!=5) return false;
        //排序
        for(int i=4;i>0;i--){
            for(int j=0;j<i;j++){
                if(numbers[j]>numbers[j+1])
                    swap(numbers,j,j+1);
            }
        }
        //0
        int count0=0,index=0,temp=1;
        while(index<4){
            if(numbers[index]==0){
                count0++;
                index++;
            }
            else{
                if(numbers[index+1]==numbers[index]+temp){
                    temp=1;
                    index++;
                }
                else{
                    if(count0>0){
                        count0--;
                        temp++;
                    }
                    else return false;
                }
            }
        }
        return true;
    }
};

58. 孩子們的遊戲(圓圈中最後剩下的數)

直接按照題目的思路用鏈表寫的代碼,一直以來很害怕鏈表,改了兩下就成功了相當開心。

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        if(n<1 || m<1) return -1;
        ListNode* phead=new ListNode(0);
        phead->next=NULL;
        ListNode* head=phead;
        ListNode* temp;
        for(int i=1;i<n;i++){
            temp=new ListNode(i);
            head->next=temp;
            head=head->next;
        }
        head->next=phead;
        head=head->next;
        int count=0;
        while(head!=NULL){
            if(count==m-2){
                if(head==head->next->next){
                    head->next=NULL;
                    break;
                }
                else
                    head->next=head->next->next;
                count=-1;
            }
            head=head->next;
            count++;
        }
        return head->val;
    }
};

59. 求1+2+3+4+~+n

class Solution {
public:
    int Sum_Solution(int n) {
        //短路求值,與的判斷條件下,當前面的條件判斷不符合,後面將不計算。
        int res=n;
        res && (res+=Sum_Solution(n-1));
        return res;
    } 
};

60. 不用加減乘除做加法

class Solution {
public:
    int Add(int num1, int num2)
    {
        if(num1==num2) return num1<<1;
        //以 異或 算出 不進位的和
        //以 與 算出進位的位置
        int sum,carry;
        while(num2!=0){
            //當不再有進位時停止
            sum=num1^num2;
            carry=(num1&num2)<<1;
            num1=sum;
            num2=carry;
        }
        return num1;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章