OJ连接html
先建立一个空链表头节点,而后依次从两个有序链表中选取最小的进行尾插操做进行合并。c++
/** * 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 == NULL) return l2; else if(l2 == NULL) return l1; ListNode* head = NULL, *tail = NULL; //建立空链表的头,方便下面进行尾插 head = tail = new ListNode; while(l1 && l2) { // 取小的进行尾插 if(l1->val < l2->val) { tail->next = l1; tail = tail->next; l1 = l1->next; } else { tail->next = l2; tail = tail->next; l2 = l2->next; } } //其中一个链表剩余节点挂到后面 if(l1) tail->next = l1; else tail->next = l2; ListNode* list = head->next; delete head; return list; } };
OJ连接:web
快慢指针法 fast, slow, 首先让fast先走k步,而后fast,slow同时走,fast走到末尾时,slow走到倒数第k个节点。面试
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { ListNode* slow = pListHead; ListNode* fast = slow; // 让fast指针先走K步,跟slow指针拉开K步的差距 while(k--) { // 这里须要注意链表可能没有K步长 if(fast) fast = fast->next; else return NULL; } // fast到尾时,slow指向倒数第k个 while(fast) { slow = slow->next; fast = fast->next; } return slow; } };
OJ连接数据结构
/** * 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) { int lenA = 0, lenB = 0; ListNode* curA = headA, *curB = headB; //先计算两个链表的长度 while(curA) { ++lenA; curA = curA->next; } while(curB) { ++lenB; curB = curB->next; } int gap = abs(lenA-lenB); struct ListNode* longList = headA, *shortList = headB; if(lenA < lenB) { longList = headB; shortList = headA; } //让长链表先走他们之间的长度差 while(gap--) { longList = longList->next; } //两个链表同时走,直到遇到相同的节点 while(longList && shortList) { if(longList == shortList) { return longList; } else { longList = longList->next; shortList = shortList->next; } } return NULL; } };
判断带环的OJ连接:https://leetcode-cn.com/problems/linked-list-cycle/ide
求环的入口点OJ连接:https://leetcode-cn.com/problems/linked-list-cycle-ii/svg
公式推导如上图所示, 若是链表存在环,则fast和slow会在环内相遇,定义相遇点到入口点的距离为X,定义环的长度为C,链表头到入口点的距离为L,slow进入环以前,fast已经在环中跑了N圈了,fast在slow进入环以后一圈内追上slow,则会得知:
slow所走的步数为:L + X
fast所走的步数为:L + X + N * C
而且fast所走的步数为slow的两倍,故:
2*(L + X) = L + X + N * C
即: L = N * C - X
因此从相遇点开始slow继续走,让一个指针从头开始走,相遇点即为入口节点学习
/** * 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) { ListNode* slow = head; ListNode* fast = head; while(fast && fast->next) { slow = slow->next; fast = fast->next->next; if(slow == fast) return true; } return false; } };
/** * 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* slow = head; ListNode* fast = head; while(fast && fast->next) { slow = slow->next; fast = fast->next->next; //走到相遇点 if(slow == fast) { // start从链表的头开始走,meet从相遇点开始走,第一次碰到的点就是入口点,这是上面的公式证实出来的 ListNode* meet = slow; ListNode* start = head; while(meet != start) { meet = meet->next; start = start->next; } return meet; } } return NULL; } };
上述的内容,若是你没有明白的地方,这是咱们录制的视频讲解,请参考.net
数据结构常见链表面试题剖析(上)3d
若是你对我写的内容感兴趣,而且对你有帮助,请你点个赞哦
你对哪些面试题感兴趣,你能够留言,咱们会出视频,带你学习哦~
上一篇:http://www.javashuo.com/article/p-apkmcalx-nb.html
下一篇:http://www.javashuo.com/article/p-nyydtwso-mv.html