Linked List 总结

本文深入探讨了链表的各种操作,包括查找交点、删除重复项、移除倒数第N个节点等,并提供了详细的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




struct ListNode 
{
    int val;
    ListNode *next;
    ListNode() {}
    ListNode(int x) : val(x), next(NULL) {}
};

void list_print(ListNode * head);

class Solution 
{
public:

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) 
    {
        int sizeA(0), sizeB(0);
        ListNode *p1(headA), *p2(headB);
        while(p1 != NULL)
        {
            sizeA ++;
            p1 = p1->next;
        }

        while(p2 != NULL)
        {
            sizeB ++;
            p2 = p2->next;
        }

        int size_diff(0);
        size_diff = abs(sizeA - sizeB);
        p1 = headA;
        p2 = headB;

        if(sizeA > sizeB)
        {
            for(int i=0; i<size_diff; i++)
            {
                p1 = p1->next;
            }
        }
        else
        {
            for(int i=0; i<size_diff; i++)
            {
                p2 = p2->next;
            }
        }

        while(p1 != NULL)
        {
            if(p1 == p2)
            {
                return p1;
            }
            p1 = p1->next;
            p2 = p2->next;
        }
        return NULL;
    }

    bool hasCycle(ListNode *head)
    {
        ListNode *p1(head), *p2(head);
        while(p2 != NULL && p2->next != NULL)
        {
            p1 = p1->next;
            p2 = p2->next->next;
            if(p1 == p2) return true;
        }
        return false;
    }

    ListNode* deleteDuplicates(ListNode* head) 
    {
        if(head == NULL) return head;
        bool action(false);
        int cmp(0);
        while(head->next != NULL && head->next->val == head->val)
        {
            action = true;
            cmp = head->val;
            while(head != NULL && head->val == cmp && action == true)
            {
                head = head->next;
            }   
            action = false;

            if(head == NULL) return head;
        }   

        ListNode *p(head);
        while(p->next != NULL && p->next->next != NULL)
        {
            if(p->next->val == p->next->next->val)
            {
                action = true;
                cmp = p->next->val;
                //p->next = p->next->next;
                while(p->next != NULL && p->next->val == cmp && action == true)
                {
                    p->next = p->next->next;
                }
                action = false;
            }
            else
            {
                p = p->next;
            }
        }
        return head;    
    }
    /*  
    ListNode* deleteDuplicates(ListNode* head) 
    {
        if(head == NULL) return head;
        while(head->next != NULL && head->next->val == head->val)
        {
            head = head->next;
        }       
        ListNode *p(head);
        while(p->next != NULL && p->next->next != NULL)
        {
            if(p->next->val == p->next->next->val)
            {
                p->next = p->next->next;
            }
            else
            {
                p = p->next;
            }
        }
        return head;            
    }
    */

    ListNode* removeNthFromEnd(ListNode* head, int n) 
    //assume this n is always valid
    {
        if(head == NULL) return head;
        if(n == 0) return head;
        ListNode *p1(head), *p2(head);
        for(int i=0; i<n; i++)
        {
            p2 = p2->next;
        }
        //cout << "ok1\n";
        if(p2 == NULL)
        {
            head = head->next;
            return head;
        }
        //cout << "ok2\n";
        while(p2->next != NULL)
        {
            p1 = p1->next;
            p2 = p2->next;
        }
        p1->next = p1->next->next;
        return head;
    }

    ListNode* rotateRight(ListNode* head, int k) 
    {
        if(head == NULL || head->next == NULL) return head;
        int size(0);
        ListNode *t(head);
        while(t->next != NULL)
        {
            size ++;
            t = t->next;
        }
        size ++;

        k = k % size;
        if(k == 0) return head;

        ListNode *p(head);
        for(int i=0; i<size-k-1; i++)
        {
            p = p->next;
        }
        t->next = head;
        head = p->next;
        p->next = NULL; 
        return head;    
    }

    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        ListNode *l3(NULL);

        if(l1 == NULL) 
        {
            return l2;
        }
        if(l2 == NULL) 
        {
            return l1;
        }
        //after this point, l1 and l2 both have a size of 1 or more


        ListNode *p1(l1), *p2(l2), *p3(l3);
        int carry(0);


        ListNode *new_node_p(NULL);

        new_node_p = new ListNode(0);
        l3 = new_node_p;
        p3 = l3;
        new_node_p = NULL;

        while(p1 != NULL && p2 != NULL)
        {
            int sum(0); 
            sum = p1->val + p2->val + carry;
            carry = 0;
            if(sum >= 10)
            {
                p3->val = sum - 10;
                carry = 1;
            }
            else
            {
                p3->val = sum;
            }
            p1 = p1->next;
            p2 = p2->next;

            if( p1 != NULL && p2 != NULL )
            {
                new_node_p = new ListNode(0);
                p3->next = new_node_p;
                p3 = p3->next;
                new_node_p = NULL;
            }
        }
        //after this point, p1 == NULL || p2 == NULL
        if( (p1 == NULL && p2 == NULL) && (carry == 1) )
        {
            new_node_p = new ListNode(1);
            p3->next = new_node_p;
            p3 = p3->next;
            carry = 0;
            new_node_p = NULL;
        }

        //cout << "p1 != NULL\n";
        //list_print(l3);
        //cin.get();    
        if(p1 != NULL)
        {       
            while(p1 != NULL)
            {
                new_node_p = new ListNode(0);
                p3->next = new_node_p;
                p3 = p3->next;
                new_node_p = NULL;

                int sum(0);
                sum = p1->val + carry;
                carry = 0;
                if(sum == 10)
                {
                    p3->val = 0;
                    carry = 1;
                }
                else
                {
                    p3->val = sum;
                }
                p1 = p1->next;
            }

            if(carry == 1)
            {
                new_node_p = new ListNode(1);
                p3->next = new_node_p;
                p3 = p3->next;
                carry = 0;
                new_node_p = NULL;
            }
        }

        //cout << "p2 != NULL\n";
        //list_print(l3);
        //cin.get();
        if(p2 != NULL)
        {
            while(p2 != NULL)
            {
                new_node_p = new ListNode(0);
                p3->next = new_node_p;
                p3 = p3->next;
                new_node_p = NULL;

                int sum(0);
                sum = p2->val + carry;
                carry = 0;
                if(sum == 10)
                {
                    p3->val = 0;
                    carry = 1;
                }
                else
                {
                    p3->val = sum;
                }
                p2 = p2->next;          
            }

            //cout << "Inside of p2 != NULL\n";
            //list_print(l3);
            //cin.get();

            if(carry == 1)
            {
                new_node_p = new ListNode(1);
                p3->next = new_node_p;
                p3 = p3->next;
                carry = 0;
                new_node_p = NULL;
            }
        }
        //cout << "return l3\n";
        //cin.get();
        return l3;      
    }

    ListNode* swapPairs(ListNode* head) 
    {
        if(head == NULL || head->next == NULL) return head;
        //after this point, all in coming linked lists have a size of 2 or more

        ListNode *tmp;
        tmp = head;
        head = head->next;
        tmp->next = head->next;
        head->next = tmp;
        //finish the swap of first pair


        ListNode *p;
        p = head->next;

        while(p->next != NULL && p->next->next != NULL)
        //make sure that there is at least one more pair to swap
        //if none or just one, just skip as nothing is to swap
        {
            tmp = p->next->next->next;
            p->next->next->next = p->next;
            p->next = p->next->next;
            p->next->next->next = tmp;

            p = p->next->next;
        }
        return head;
    }

    ListNode* removeElements(ListNode* head, int val)
    {
        if(head == NULL) return head;

        while(head != NULL && head->val == val)
        {
            head = head->next;
        }
        if(head == NULL) return head;

        ListNode *p;
        p = head;
        while(p->next != NULL)
        {
            if(p->next->val == val)
            {
                p->next = p->next->next;
            }
            else
            {
                p = p->next;
            }
        }
        return head;
    }

    ListNode* insertionSortList(ListNode* head) 
    //"insertion sort"
    {
        if(head == NULL || head->next == NULL) return head;
        //after this point, all in coming linked lists have a size of 2 or more

        ListNode *p, *next_p, *n;
        //ListNode *end,
        //end = head;
        p = head->next;
        next_p = p->next;

        head->next = NULL;
        //end->next = NULL;

        while(p != NULL)
        {
            cout << "L0 ";
            p->next = NULL;

            if(head->val > p->val)
            {
                p->next = head;
                head = p;
            }
            else
            {
                n = head;
                while(n->next != NULL)
                {
                    //cout << "L1 ";
                    if(n->next->val > p->val)
                    {
                        p->next = n->next;
                        n->next = p;
                        break;
                    }
                    n = n->next;
                }
                n->next = p;
            }
            //insertion finished
            //prepare for next item

            p = next_p;
            if(next_p != NULL)
            {
                next_p = next_p->next;
            }

            list_print(head);
        }

        return head;        
    }


    ListNode* sortList(ListNode* head) 
    //decided to use "marge sort", recurrence as the way to solve this problem
    {
        if(head == NULL) return head;
        if(head->next == NULL) return head;
        //merge(left_par, right_par);
        ListNode *fast, *slow;
        fast = head;
        slow = head;
        while(fast->next != NULL && fast->next->next != NULL)
        {
            fast = fast->next->next;
            slow = slow->next;
        }
        fast = slow->next;
        slow->next = NULL;
        slow = head;
        return merge(sortList(fast), sortList(slow));
        //step 1. using fast-slow pointers to find the middle point of this sortlist
        //and to define two parts
        //setp 2. using sortlist recursively
        //step 3. merge
    }

    ListNode* merge(ListNode* l1, ListNode* l2)
    {
        ListNode *new_head(NULL), *p(NULL);

        if(l1 == NULL) return l2;
        if(l2 == NULL) return l1;

        if(l1->val < l2->val)
        {
            new_head = l1;

            l1 = l1->next;                  
        }   
        else
        {
            new_head = l2;

            l2 = l2->next;
        }

        p = new_head;
        p->next = NULL; 

        while(l1 != NULL && l2 != NULL)
        {
            if(l1->val < l2->val)
            {
                p->next = l1;
                l1 = l1->next;
            }   
            else
            {
                p->next = l2;
                l2 = l2->next;
            }

            p = p->next;
            p->next = NULL; 
        }

        if(l1 != NULL)
        {
            p->next = l1;
        }
        else
        {
            p->next = l2;
        }
        return new_head;
    }
};


void list_print(ListNode * head)
{
    ListNode *tmp = head;
    cout << "list_print: ";
    if(tmp == NULL)
    {
        cout << "\n"; 
        return;
    }   
    while(tmp->next != NULL)

    {
        cout << " " << tmp->val;
        tmp = tmp->next;
    }
    cout << " " << tmp->val;
    cout << "\n";
    return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值