(1)题目:输入两个链表,找出它们的第一个公共节点。
思路:
1)计算出链表1的长度;
2)计算出链表2的长度;
3)计算出链表1和链表2的长度差dif;
4)长链表先走dif步,然后两条链表一起走,直到两个链表的节点第一次相等为止,此时指针位置即为所求。
代码实现:
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode *p1=pHead1;
ListNode *p2=pHead2;
int len1=0,len2=0,dif=0;
while(p1!=NULL){
p1=p1->next;
len1++;
}
while(p2!=NULL){
p2=p2->next;
len2++;
}
if(len1>len2){
dif=len1-len2;
p1=pHead1;
p2=pHead2;
}
else{
dif=len2-len1;
p1=pHead2;
p2=pHead1;
}
for(int i=0;i<dif;i++){
p1=p1->next;
}
while(p1!=NULL && p2!=NULL){
if(p1==p2)
break;
p1=p1->next;
p2=p2->next;
}
return p1;
}
};
(2)题目:删除链表中重复的节点
代码实现:
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead==NULL)
return NULL;
if (pHead!=NULL && pHead->next==NULL)
return pHead;
ListNode* current;
if ( pHead->next->val==pHead->val){
current=pHead->next->next;
while (current != NULL && current->val==pHead->val)
current=current->next;
return deleteDuplication(current);
}
else {
current=pHead->next;
pHead->next=deleteDuplication(current);
return pHead;
}
}
};
(3)题目:sort-list:Sort a linked list in O(n log n) time using constant space complexity.
思路:
(1)快慢指针法将链表从中间分为了l1,l2两部分
(2)左右两部分链表分别递归进行排序
(3)合并两个子链表
代码实现:
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head == NULL || head->next == NULL)
return head;
ListNode* p = head;
ListNode* q = head->next;
while(q && q->next)
{
p = p->next;
q = q->next->next;
}
ListNode* l1 = sortList(p->next);
p->next = NULL;
ListNode* l2 = sortList(head);
return Merge(l1,l2);
}
ListNode* Merge(ListNode* l1,ListNode* l2)
{
ListNode L(0);
ListNode* p = &L;
while(l1&&l2)
{
if(l1->val < l2->val)
{
p->next = l1;
l1=l1->next;
}
else
{
p->next = l2;
l2=l2->next;
}
p = p -> next;
}
if(l1 != NULL)
p->next = l1;
if(l2 != NULL)
p->next = l2;
return L.next;
}
};
(4)题目:Given a singly linked list L: L 0→L 1→…→L n-1→L n,
reorder it to: L 0→L n →L 1→L n-1→L 2→L n-2→…
You must do this in-place without altering the nodes’ values.
For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.
思路:
(1)快慢指针法找到中间节点
(2)对链表后半部分进行逆序
(3)合并前半部分和逆序后的后半部分
代码实现:
class Solution {
public:
void reorderList(ListNode *head) {
if(head == NULL || head->next == NULL || head->next->next == NULL)
return;
//快慢指针找中点
ListNode* fast = head;
ListNode* low = head;
while(fast->next != NULL && fast->next->next != NULL)
{
fast = fast->next->next;
low = low->next;
}
//对low后面的部分逆序
fast = low->next;
low->next = NULL;
while(fast != NULL){
ListNode* temp = fast->next;
fast->next = low->next;
low->next = fast;
fast = temp;
}
//合并low前面和后面两部分
ListNode* p = head;
ListNode* q = low->next;
while(p != NULL && q != NULL){
low->next = q->next;
q->next = p->next;
p->next = q;
p = q->next;
q = low->next;
}
}
};
(5)题目:Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given1->4->3->2->5->2and x = 3,
return1->2->2->4->3->5..
思路:
(1)新建两个节点分别为fast和slow,分别指向两个头结点;
(2)从头到尾遍历,小于x值的节点连接到p1,大于等于x的值的节点链接到p2;
(3)最后将两个链表相连。
代码实现:
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head == NULL)
return NULL;
ListNode* fast = new ListNode(0);
ListNode* slow = new ListNode(0);
ListNode* p1 = slow;
ListNode* p2 = fast;
ListNode *p = head;
while(p!=NULL)
{
if(p->val < x)
{
p1->next = p;
p1 = p1->next;
}
else
{
p2->next = p;
p2 = p2->next;
}
p = p->next;
}
p2->next = NULL;
p1->next = fast->next;
return slow->next;
}
};