链接基础 链表常考的题目
链表的常考题目
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; } };
2 相交链表
方法一:利用哈希表
/** * 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; } };
3 环形链表
方法一:利用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; } };
3 环形链表 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; } };
4 分隔链表
方法:利用临时头结点
/** * 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; } };
5 复制带随机指针的链表
方法一:利用一个哈希表,存储一个地址到节点位置的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); } };