链接基础 链表常考的题目

链表的常考题目

1.1 反转链表

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode * new_head = nullptr;
        while(head)
        {
            ListNode* next = head->next;
            head->next = new_head;
            new_head = head;
            head = next;
        }
        return new_head;
    }
};

 

 

1.2 反转链表 II

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        int change_len = n-m+1;
        ListNode *pre_head = nullptr;
        ListNode *result = head;
        while(head && --m)
        {
            pre_head = head;
            head = head->next;
        }
        ListNode* tail = head;
        ListNode* new_head = nullptr; 
        while(head && change_len)
        {
            ListNode * next = head->next;
            head->next = new_head;
            new_head = head;
            head = next;
            change_len--;
        }
        tail->next = head;
        if(pre_head!=nullptr)
        {
            pre_head->next = new_head;
        }
        else
        {
            result = new_head;
        }
        return result;
    }
};

 

相交链表

方法一:利用哈希表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        unordered_set<ListNode*> s;
        while(headB)
        {
            s.insert(headB);
            headB = headB->next;
        }

        while(headA)
        {
            if(s.count(headA))
                return headA;
            headA = headA->next;
        }
        return nullptr;
    }
};

方法二:双指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
int get_list_length(ListNode *head)
{
    int len = 0;
    while(head)
    {
        len++;
        head = head->next;
    }
    return len;
}
ListNode * movehead(int longlen, int shortlen, ListNode* head)
{
    int dif = longlen-shortlen;
    while(dif)
    {
        head = head->next;
        dif--;
    }
    return head;
}
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int la = get_list_length(headA);
        int lb = get_list_length(headB);
        if (la>lb){
            headA = movehead(la,lb,headA);
        }
        else
        {
            headB = movehead(lb,la,headB);
        }
        while(headA && headB)
        {
            if(headA==headB)
            {
                return headA;
            }
            headA = headA->next;
            headB = headB->next;
        }
        return nullptr;
    }
};

 

环形链表

方法一:利用set

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        set<ListNode*>s;
        while(head)
        {
            if (s.count(head))
                return true;
            s.insert(head);
            head = head->next;
        }
        return false;
    }
};

方法二:快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head==nullptr || head->next == nullptr)
            return false;
        ListNode *slow = head;
        ListNode *fast = head->next;
        while(slow != fast)
        {
            if (fast==nullptr || fast->next==nullptr)
                return false;
            slow = slow->next;
            fast = fast->next->next;
        }
        return true;
    }
};

 

环形链表 II

方法一:利用set

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode *> st;
        while(head!=NULL){
            if(st.count(head)) return head;
            st.insert(head);
            head=head->next;
        }
        return NULL;
    }
};

方法二:快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *fast = head, *slow = head;

        while (fast and fast->next) { //写的时候注意 fast == slow 不要写在这儿,因为刚开始走的时候两个都是 head
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
                break;
            }
        }

        if (fast == NULL || fast->next == NULL) {
            return NULL;
        }

        ListNode *offset = head;
        while (offset != fast) {
            offset = offset->next;
            fast = fast->next;
        }
        return offset;
    }
};

 

分隔链表

方法:利用临时头结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode lesshead(0);
        ListNode morehead(0);
        ListNode *less = &lesshead;
        ListNode *more = &morehead;

        while(head)
        {
            if (head->val < x)
            {
                less->next = head;
                less = less->next;
            }
            else
            {
                more->next = head;
                more = more->next;
            }
            head = head->next;
        }
        less->next = morehead.next;
        more->next= nullptr;
        return lesshead.next;
    }
};

 

复制带随机指针的链表

方法一:利用一个哈希表,存储一个地址到节点位置的map

/*
// 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) {
        map<Node*, int> node_map;
        vector< Node*> node_vec;
        Node *ptr = head;
        int i= 0;
        while(ptr)
        {
            node_vec.push_back(new Node(ptr->val));
            node_map[ptr] = i;
            ptr = ptr->next;
            i++;
        }
        node_vec.push_back(0);
        ptr = head;
        i = 0;
        while(ptr)
        {
            node_vec[i]->next = node_vec[i+1];
            if(ptr->random)
            {
                int id = node_map[ptr->random];
                node_vec[i]->random = node_vec[id];
            }
            ptr = ptr->next;
            i++;
        }
        return node_vec[0];
    }
};

方法二:不使用辅助空间的情况下实现O(N)的时间效率

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

void colneNodes(Node* head)
{
    Node* ptr = head;
    while(ptr)
    {
        Node* pclone = new Node(ptr->val);
        pclone->next = ptr->next;
        pclone->random = nullptr;
        ptr->next = pclone;
        ptr = pclone->next;
    }
}

void connectRandom(Node* head)
{
    Node *ptr = head;
    while(ptr)
    {
        Node * pclone = ptr->next;
        if (ptr->random != nullptr)
        {
            pclone->random = ptr->random->next;
        }
        ptr = pclone->next;
    }
}

Node* Reconnect(Node* head) 
{
    Node *ptr = head;
    Node *pcloneHead = nullptr;
    Node *pcloneNode = nullptr;

    if (ptr)
    {
        pcloneHead = pcloneNode = ptr->next;
        ptr->next = pcloneNode->next;
        ptr = ptr->next;
    }
    while(ptr)
    {
        pcloneNode->next = ptr->next;
        pcloneNode = pcloneNode->next;
        ptr->next = pcloneNode->next;
        ptr = ptr->next;
    }
    return pcloneHead;
}
 
class Solution {
public:
    Node* copyRandomList(Node* head) {
       colneNodes(head);
       connectRandom(head);
       return Reconnect(head);
    }
};

 

6.1 合并两个有序链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */


class Solution {
public:
    ListNode* mergeTwoList(ListNode *a, ListNode *b)
    {
        if (a == nullptr || b == nullptr)
            return a ? a : b;
        
        ListNode *ptr
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        vector<ListNode *> v;
        for (int i=0;i<lists.size();i++)
        {
            ListNode* head = lists[i];
            while(head)
            {
                v.push_back(head);
                head = head->next;
            }
        }
        if(v.size()==0)
            return nullptr;
        
        sort(v.begin(),v.end(),cmp);
        for (int i=1;i<v.size();i++)
        {
            v[i-1]->next = v[i];
        }
        v[v.size()-1]->next = nullptr;
        return v[0];
    }
};

 

6.2 合并K个排序链表

方法一:排序后相连

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

bool cmp(const ListNode* a, const ListNode* b)
{
    return a->val < b->val;
}
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        vector<ListNode *> v;
        for (int i=0;i<lists.size();i++)
        {
            ListNode* head = lists[i];
            while(head)
            {
                v.push_back(head);
                head = head->next;
            }
        }
        if(v.size()==0)
            return nullptr;
        
        sort(v.begin(),v.end(),cmp);
        for (int i=1;i<v.size();i++)
        {
            v[i-1]->next = v[i];
        }
        v[v.size()-1]->next = nullptr;
        return v[0];
    }
};

方法二:分治后相连

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */


class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1==nullptr)
            return l2;
        if (l2==nullptr)
            return l1;
        ListNode * first = new ListNode(0);
        ListNode * head = first;
        while (l1 != nullptr && l2 != nullptr)
        {
            if(l1->val <l2->val)
            {
                first->next = l1;
                l1 = l1->next;
            }
            else
            {
                first->next = l2;
                l2 = l2->next;
            }
            first = first->next;
        }
        first->next = l1 == nullptr ? l2 : l1;
        
        return head->next;
    }

    ListNode* merge(vector<ListNode*>& lists, int l, int r)
    {
        if (l==r)
            return lists[l];
        if(l>r)
            return nullptr;
        int mid = (l + r) >> 1;
        return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return merge(lists, 0, lists.size() - 1);
    }
};

 

posted @ 2020-07-14 15:23  r1-12king  阅读(138)  评论(0编辑  收藏  举报