【小菜鸡刷题记】---链表篇

剑指 Offer 06. 从尾到头打印链表

剑指 Offer 06. 从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

输入:head = [1,3,2]
输出:[2,3,1]

反转实现

class Solution {
    
    
public:
    vector<int> reversePrint(ListNode* head) {
    
    
        vector<int> v;
        ListNode* cur=head;
        while(cur)
        {
    
    
            v.push_back(cur->val);
            cur=cur->next;
        }
        reverse(v.begin(),v.end());
        return v;
    }
};

利用栈的特性

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

    }
};

递归实现

class Solution {
    
    
public:
    vector <int> v; 
    vector<int> reversePrint(ListNode* head) {
    
    
    	// vector <int> v; 
        // if(head==nullptr)
        // {
    
    
        //     return v;
        // }
        // v=reversePrint(head->next);
        // v.push_back(head->val);
        // return v;
        
        vector<int> v;
        if(head!=nullptr)
        {
    
    
            if(head->next!=nullptr)
            {
    
    
                v=reversePrint(head->next);
            }
            v.push_back(head->val);
        }
        return v;
    }
};

剑指 Offer 24. 反转链表

剑指 Offer 24. 反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL

头插法

class Solution {
    
    
public:
    ListNode* reverseList(ListNode* head) {
    
    
        ListNode* newhead=nullptr;
        ListNode* cur=head;
        while(cur)
        {
    
    
        	//保存下一个节点
            ListNode* next=cur->next;
            cur->next=newhead;
            newhead=cur;
            cur=next;
        }
        return newhead;
    }
};

剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
在我另一篇文章中有关于第二种方法的详解

示例 1: 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

哈希

以空间换时间:复制原链表中的节点N’,与原节点构成键值对<N,N’>添加到map集合中,然后递归复制下一节点和随机指针

class Solution {
    
    
public:
    unordered_map<Node*,Node*> map;
    Node* copyRandomList(Node* head) {
    
    
        if(head==nullptr)
        {
    
    
            return nullptr;
        }
        if(map.count(head)<1)
        {
    
    
            Node* copyNode=new Node(head->val);
            //map.insert({head,copyNode});
            map.insert(std::make_pair(head,copyNode));//添加到map中
            
            copyNode->next=copyRandomList(head->next);//递归复制下一节点
            copyNode->random=copyRandomList(head->random);///递归复制随机指针
        }
        return map[head];//返回pair.second的引用
    }
};

迭代+节点拆分

/*
// 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:
    //1.复制原链表的每个节点并添加的原节点的下一节点
    void copyNodeAndNext(Node* head)
    {
    
    
        Node* cur=head;
        while(cur)
        {
    
    
            Node* copyNode=new Node(cur->val);
            copyNode->next=cur->next;
            cur->next=copyNode;
            cur=copyNode->next;
        }
    }

    //2.复制原链表节点的随机指针
    void copyNodeAndRandom(Node* head)
    {
    
    
        Node* cur=head;
        while(cur)
        {
    
    
           Node* copyNode=cur->next;
           //如果原链表的随机指针不为空,那么复制节点的随机指针指向的节点
           //就是原链表随机指针指向节点的下一个节点
           if(cur->random)
           {
    
    
               copyNode->random=cur->random->next;
           }
            cur=copyNode->next;

        }
    }
    //3.将复制好的链表拆下来
    Node* deatchList(Node* head)
    {
    
    
        Node* cur=head;
        Node* copyhead=new Node(-1);//创建头结点,方便拆分组合
        Node *copytail=copyhead;
        while(cur)
        {
    
    
            Node* copyNode=cur->next;
            Node* next=copyNode->next;
            //保留原链表
            cur->next=next;
            //分割出新链表
            copytail->next=copyNode;
            copytail=copytail->next;
            cur=next;
        }
        Node* newhead=copyhead->next;
        delete copyhead;
        return newhead;

    }
    
    Node* copyRandomList(Node* head) {
    
    
        copyNodeAndNext(head);
        copyNodeAndRandom(head);
        return deatchList(head);

    }
};

猜你喜欢

转载自blog.csdn.net/m0_54469145/article/details/130706607