刷题第二天:从尾到头打印;翻转链表;复杂链表复制

例1

题号:剑指offer 06, 难度:简单

题目描述:

解题思路:

我用了个栈改变顺序。利用栈先进后出的特性,把元素逐个压进去,再弹出来顺序就反了。

具体代码:

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        stack<int> nodes;
        vector<int> res;
        ListNode * pNode = head;
        while(pNode != NULL)
        {
            nodes.push(pNode->val);
            pNode = pNode->next;
        }
        while(!nodes.empty())
        {
            res.push_back(nodes.top());
            nodes.pop();
        }
        
        return res;
        
    }
};

例2

题号:剑指offer 24, 难度:简单

题目描述:

解题思路:

假设共有五个节点,1->2->3->4->5,1<-2<-3  4->5,刚翻转完3,可以看到链表是断开的,所以翻转3的时候要保存3->next,用pNext保存。

那翻转链表就可以抽象为两步:

1、保存下一个节点

2、当前节点指向前一个节点。

具体代码:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode * pReversedHead = NULL;
        ListNode * pNode = head;
        ListNode * pPre = NULL;

        while(pNode != NULL)
        {
            ListNode *pNext = pNode->next;
            if (pNext == NULL)
                pReversedHead = pNode;
            
            pNode->next = pPre;

            pPre = pNode;           
            pNode = pNext;
        }

        return pReversedHead;
    }
};

例3

题号:剑指offer 35, 难度:中等

思路分三步,每个节点后面克隆一个节点,然后把克隆节点的复杂节点弄好,最后拆分长链表。

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        Node * node = head;
  
 
        //克隆一份  
        while(node != NULL)  //原链表每个节点后面都插入一个新节点,新节点的值和原链表一样
        {
            Node * clone = new Node(node->val);
            clone->next = node->next;
            node->next = clone;
            node = clone->next;
        }


        //建立random指针
        node = head;       

        while(node != NULL) 
        {   //从头遍历一遍,如果原链表的节点存在random指针,那这个random指针指向位置的后一个节点,就是新链表的random指针指向的位置。

            Node * clone = node->next;
            if(node->random != NULL)
            {    
                clone->random = node->random->next;
            }
            node = clone->next;
        }

        //拆分
        node = head;
        Node *cloneHead = NULL;
        Node *cloneNode = NULL;

        if(node != NULL) //设置好要拆分的两个链表的头
        {
            cloneHead = cloneNode = node->next;
            node->next = cloneNode->next;
            node = node->next;
        }

        while(node != NULL) //把对应的节点放到链表头后面
        {
            cloneNode->next = node->next;
            cloneNode = cloneNode->next;
            node->next = cloneNode->next;
            node = node->next;

        }


        return cloneHead;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值