编程练习:链表习题(上)


(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;
    }
};

猜你喜欢

转载自blog.csdn.net/zjx624bjh/article/details/81383363