每日六題-劍指offer(三)

劍指offer之每日六題

1.調整數組順序使奇數位於偶數前面
2.鏈表的倒數第k個結點
3.反轉鏈表
4.合併兩個排序的鏈表
5.樹的子結構
6.二叉樹的鏡像

1.調整數組順序使奇數位於偶數前面

/**
類似於冒泡排序
將奇數推到前面
**/
class Solution {
public:
    void reOrderArray(vector<int> &array) {
        for (int i = 0; i < array.size();i++)
        {
            for (int j = array.size()-1; j>i;j--)
            {
                if (array[j] % 2 == 1 && array[j - 1]%2 == 0)
                {
                    swap(array[j], array[j-1]);
                }
            }
        }
    }
};

2.鏈表的倒數第k個結點

/**
類似於用一個長度爲k的尺子
p1代表尺子尾,p是尺子頭,當p1到最後面時,p剛好是倒數第k個
**/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* p, int k) {
        ListNode* p1=p;
        for(int i=0;i!=k;++i)
            if(!p1)return nullptr;
        else
            p1=p1->next;
        while(p1){
            p1=p1->next;
            p=p->next;
        }
        return p; 
    }
};

3.反轉鏈表

/**
鏈表反轉在劍指offer(一)的那一題裏面詳細介紹了
**/
class Solution {
public:
    ListNode* ReverseList(ListNode* head) {
        if(!head) return NULL;
        ListNode* pre=head;
        ListNode* now=head->next;
        ListNode* next=head->next->next;
        while(now){
            next=now->next;
            now->next=pre;
            pre=now;
            now=next;
        }
        head->next=NULL;
        return pre;
    }
};

4.合併兩個排序的鏈表

/**
比較,合併,應該沒毛病
1.其中一個鏈表爲空,返回另一個鏈表
2.比較頭結點,講較小的那個作爲總的頭結點
3.當兩者非空,比較值,小的放前面
4.其中一個空了之後,把另一個鏈表的剩餘結點給總結點
**/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(!pHead1)
            return pHead2;
        if(!pHead2)
            return pHead1;
        ListNode* Head;
        ListNode* p;
        if(pHead1->val<=pHead2->val){
            Head=pHead1;
            pHead1=pHead1->next;
        }
        else{
            Head=pHead2;
            pHead2=pHead2->next;
        }  
        p=Head;
        while(pHead1&&pHead2){
            if(pHead1->val<=pHead2->val){
                p->next=pHead1;
                pHead1=pHead1->next;
                p=p->next;
            }               
            else{
                p->next=pHead2;
                pHead2=pHead2->next;
                p=p->next;
            }                
        }
        if(pHead1 == NULL)
            p->next = pHead2;
        if(pHead2 == NULL)
            p->next = pHead1;
        return Head;
    }
}; 

5.樹的子結構

/**
遞歸大法真的屌,先判斷A和B的根節點,如果相等,判斷B是否是A的子樹
判斷方法也用了遞歸,如果B先遍歷完,說明B是A的子樹,返回真值,如果
A先遍歷完,顯而易見
**/
class Solution {
    bool isSubtree(TreeNode* pRootA, TreeNode* pRootB) {
        if (pRootB == NULL) return true;
        if (pRootA == NULL) return false;
        if (pRootB->val == pRootA->val) {
            return isSubtree(pRootA->left, pRootB->left)
                && isSubtree(pRootA->right, pRootB->right);
        } else return false;
    }
public:
    bool HasSubtree(TreeNode* pRootA, TreeNode* pRootB)
    {
        if (pRootA == NULL || pRootB == NULL) return false;
        return isSubtree(pRootA, pRootB) ||
            HasSubtree(pRootA->left, pRootB) ||
            HasSubtree(pRootA->right, pRootB);
    }
};

6.二叉樹的鏡像

/**
從上到下分解一下,其實就是把每個結點的左右子樹交換一下就行了
**/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        TreeNode *p;
        if(pRoot==NULL) return ;
        if(pRoot->left&&pRoot->right){
            p=pRoot->left;
            pRoot->left=pRoot->right;
            pRoot->right=p;
        }
        else if(pRoot->left&&!pRoot->right){
            pRoot->right=pRoot->left;
            pRoot->left=NULL;
        }
        else if(pRoot->right&&!pRoot->left){
            pRoot->left=pRoot->right;
            pRoot->right=NULL;
        }
        Mirror(pRoot->left);
        Mirror(pRoot->right);
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章