每日六题-剑指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);
    }
};

猜你喜欢

转载自blog.csdn.net/hengtian_real/article/details/79742963