牛客剑指offer刷题记录(三)

来源:互联网 发布:小米note软件搬家 编辑:程序博客网 时间:2024/05/21 02:20

反转链表

反转链表的主要思路是利用头插法。
假设原始链表1->2->3->4
并且再为这个链表装一个头结点:
0->1->2->3->4
问题转化为,从原始链表的第二个节点开始遍历整个链表,依次头插到原始链表中,例如0->1->2->3->4遍历链表节点2、3、4依次完成头插变成了0->4->3->2->1

我们需要一个pre节点来记录当前待头插的节点cur,以便当cur插入头部以后,pre能够连接到next节点上。

class Solution {public:    ListNode* ReverseList(ListNode* pHead) {        if(pHead==NULL)            return pHead;        ListNode* newHead= new ListNode(0);        newHead->next=pHead;        ListNode*pre=newHead->next;        ListNode*cur=pre->next;        ListNode*next=NULL;        while(NULL!=cur)        {            next=cur->next;            //头插            cur->next=newHead->next;            newHead->next=cur;            //连接断开链表            pre->next=next;            // 遍历到下个节点            cur=next;        }        return newHead->next;    }};

合并两个有序链表

不难想到合并两个有序数组的思路:

int i=0;int j=0;while(i<a.size()&&j<b.size()){    if(a[i]<b[j])    {        c.push_back(a[i++]);    }    else if(a[i]>b[j])    {        c.push_back(b[j++]);    }    else    {        c.push_back(a[i]);        ++i;        ++j;    }}//把剩余的部分添加到c中

链表操做要考虑是否产生新的节点(额外的空间),如果可以,完全可以按照数组的思路不断的new ListNode

如果原地的来做,就需要一些技巧了。

class Solution {public:    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)    {        if(pHead1==NULL)            return pHead2;        if(pHead2==NULL)            return pHead1;        ListNode*root=NULL;        if(pHead1->val<pHead2->val){            root=pHead1;            root->next=Merge(pHead1->next,pHead2);        }        else        {            root=pHead2;            root->next=Merge(pHead1,pHead2->next);        }        return root;    }};

树的子结构

判断B是不是A的子结构
主要两个步骤:
1.第一步在树A中找到和B根节点相同的节点R。
2.第二步以R为根的子树是不是包含和树B一样的结构。

如果经历了上述两步没有完成匹配,那么,我们将递归去判断其左右子树是否满足要求。

/*struct TreeNode {    int val;    struct TreeNode *left;    struct TreeNode *right;    TreeNode(int x) :            val(x), left(NULL), right(NULL) {    }};*/class Solution {private://判断是否包含子结构    bool helper(TreeNode*root1,TreeNode*root2){        if(root2==NULL)            return true;        if(root1==NULL)            return false;        if(root1->val!=root2->val)            return false;        return helper(root1->left,root2->left)&&            helper(root1->right,root2->right);    }public:    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)    {        bool result=false;        //找到相同节点        if(pRoot1!=NULL&&pRoot2!=NULL){            if(pRoot1->val == pRoot2->val)                result=helper(pRoot1,pRoot2);        //递归的完成左右子树            if(!result){                result=HasSubtree(pRoot1->left,pRoot2);            }            if(!result){                result=HasSubtree(pRoot1->right,pRoot2);            }        }        return result;    }};

二叉树的镜像

先序遍历所有节点,如果左右子节点不都为空,则交换。

class Solution {public:    void Mirror(TreeNode *pRoot) {        if(pRoot==NULL)            return ;        TreeNode* tmp=pRoot;        tmp=pRoot->left;        pRoot->left=pRoot->right;        pRoot->right=tmp;        Mirror(pRoot->left);        Mirror(pRoot->right);    }};

顺时针打印矩阵

详细解释见:blog.csdn.net/zhangxiao93/article/details/49388395
假设有矩阵
1 2 3
4 5 6
7 8 9
最终将打印1 2 3 6 9 8 7 4 5

一层一层打印,每一层有4个for循环分别表示4个方向。

class Solution {public:    vector<int> printMatrix(vector<vector<int> > matrix) {        vector<int>result;        if(matrix.size()==0||matrix[0].size()==0)            return result;        int row=matrix.size();        int col=matrix[0].size();        result.reserve(row * col);        int count=min(row,col)/2;        bool flag=((min(row,col)&0x1)==1)?true:false;        int j=0;        for(int i=0;i<count;++i){            for(int j=i;j<col-i-1;++j)//left to right                result.push_back(matrix[i][j]);            for(int j=i;j<row-i-1;++j)//up to down                result.push_back(matrix[j][col-i-1]);            for(int j=col-i-1;j>i;--j)//right to left                result.push_back(matrix[row-i-1][j]);            for(int j=row-i-1;j>i;--j)//down to up                result.push_back(matrix[j][i]);        }//end for        if(flag){            if(row==col){                result.push_back(matrix[count][count]);            }            else if(row>col){                for(int j=count;j<row-count;++j)                    result.push_back(matrix[j][count]);            }            else{//col > row                for(int j=count;j<col-count;++j)                    result.push_back(matrix[count][j]);            }        }//endif        return result;    }};
原创粉丝点击