牛客网剑指offer|中等题day2|JZ22链表中倒数最后k个结点(简单)、JZ35复杂链表的复制(复杂)、JZ77按之字形顺序打印二叉树(中等)

JZ22链表中倒数最后k个结点(简单)

链接:链表中倒数最后k个结点_牛客题霸_牛客网

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        // write code here
        //遍历一遍链表,得到它的长度n
        // 对于倒数第k个节点,要走n-k步

        ListNode *r=pHead;
        int n=0;
        while(r!=nullptr)
        {
            r=r->next;
            n++;
        }
        if(n==0)
        {
            return nullptr;
        }
        else {
          int step=n-k;//4-2=2
          if(step<0)
          {
            return nullptr;
          }
          r=pHead;
          while(step && r!=nullptr)
          {
            step--;
            r=r->next;
          }
          return r;

        }
    }
};

 JZ35复杂链表的复制(复杂)

链接:复杂链表的复制_牛客题霸_牛客网

 

 最终代码是自己写出来了。但是其中进入了几个误区:

1、误区一:觉得建立的新节点可以直接指向源节点的next和random,实际上这样做指向的还是源节点,而对于往后一个个建立的新节点,下一个next是能写的,但是random可能在下2、5个之后才创建,所以是一个难点。

2、误区二:一开始觉得可以在遍历源链表后,因为原链表的next指针域已经遍历过不再用,所以想让源节点的指针域更新为存储新节点 的地址,即A->next=A_copy;则A_copy->random=A->random->next;都理解错了

后来想到可以借助map,直接把源节点地址和新建立的节点地址一一对应,

则遍历源链表两次,第一次建立新链表,每个next更新为新节点地址;

                                第二次更新新链表的random指针域。

代码如下:

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead) {
        RandomListNode *copy_L=new RandomListNode(-1);//复制链表的头节点
        RandomListNode *p1=pHead,*p2=copy_L;


         unordered_map<RandomListNode*,RandomListNode*>umap;
        while(p1)
        {
           // cout<<p1->label<<endl;
            RandomListNode *temp=new RandomListNode(p1->label);
            p2->next=temp;
            p2=temp;

            umap[p1]=p2;
            p1=p1->next;
       
            //之所以这样,是想利用A2->random=A1->random->next;
        }

        //重新更新深拷贝链表的random域
        p2=copy_L->next;
        p1=pHead;
        while(p2 && p1)
        {
            //cout<<p2->label<<endl;
            p2->random=umap[p1->random];
            p2=p2->next;
            p1=p1->next;

        }
        return copy_L->next;
        
    }
};

 JZ77按之字形顺序打印二叉树(中等)

链接:按之字形顺序打印二叉树_牛客题霸_牛客网

 挺经典的层序遍历,看了题解还有另一种解法两个栈,但是我没有进一步了解。偷懒用了

reverse函数


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        //很显然是层序遍历,然后每层的res再reverse
        queue<TreeNode*>q;
        vector<vector<int>>v;
        if(pRoot==nullptr)
        {
            return v;
        }
        q.push(pRoot);
        //cout<<pRoot->val<<endl;
        int index=0;
        while(!q.empty())
        {
            int len =q.size();
            vector<int>res;
            for(int i=0;i<len;i++)         
            {
                TreeNode *temp=q.front();
                res.push_back(temp->val);
                q.pop();
                if(temp->left)
                {
                    q.push(temp->left);
                }
                if(temp->right)
                {
                    q.push(temp->right);
                }
            }
            if(index%2==1)
            {
             reverse(res.begin(),res.end());
            }
            /*for(auto p:res)
            {
                cout<<p<<" ";
            }
            cout<<endl;
            */
            v.push_back(res);
            index++;
        }
        return v;
        
    }
    
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值