链表习题(二)

方法一:三指针法

struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode*left=head,*right=NULL;
    if(head==NULL||head->next==head)
    {
        return head;
    }
    while(left)
    {
        struct ListNode*cur=left->next;
        left->next=right;
        right=left;
        left=cur;
    }
    return right;

}

方法二:建立一个新的头节点,然后进行头插

struct ListNode* reverseList(struct ListNode* head) {

    struct ListNode*cur=head;

    if(head==NULL)

    {

        return NULL;

    }

    struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));

    newhead->val=head->val;

    newhead->next=NULL;

    while(cur)

    {

        struct ListNode*copy=(struct ListNode*)malloc(sizeof(struct ListNode));

        copy->val=cur->val;

        copy->next=newhead->next;

        newhead->next=copy;

        cur=cur->next;

    } 

    return newhead->next;

}

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode*head=(struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode*cur1=list1;
    struct ListNode*cur2=list2;
    struct ListNode*tail=NULL;
    while(cur1&&cur2)
    {
        if(cur1->val>=cur2->val)
        {
            if(tail==NULL)
            {
                head=tail=cur2;
                cur2=cur2->next;
            }
            else
            {
                tail->next=cur2;
                tail=tail->next;
                cur2=cur2->next;
            }
        }
        else if(cur1->val<cur2->val)
        {
            if(tail==NULL)
            {
                head=tail=cur1;
                cur1=cur1->next;
            }
            else
            {
                tail->next=cur1;
                tail=tail->next;
                cur1=cur1->next;
            }
        }
    }
    if(cur1==NULL&&cur2!=NULL)
    {
        if(tail==NULL)
        {
            head=tail=cur2;
        }
        else
        {
            tail->next=cur2;
        }
    }
    else if(cur1!=NULL&&cur2==NULL)
    {
        if(tail==NULL)
        {
            head=tail=cur1;
        }
        else
        {
            tail->next=cur1;
        }
    }
    else
    {
        if(tail==NULL)
        {
            return NULL;
        }
        else
        {
            tail->next=NULL;
        }
    }
    return head;
}

方法一:分别建立两个新链表,分别进行尾插,最后组合成一条符合要求的总链表

需要注意的是尾指针要置空,否则它的最后一个节点的next指向仍可能为小于x的值,出现无法读取内存的错误

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
       struct ListNode* cur=pHead;
     struct ListNode* tail=nullptr;
     struct ListNode*ptail=nullptr;
     struct ListNode*head=nullptr;
     struct ListNode*newhead=nullptr;
        while(cur)
        {
            if(cur->val<x)
            {
                if(tail==nullptr)
                {
                    newhead=cur;
                    tail = cur;
                }
                else 
                {
                    tail->next=cur;
                    tail=tail->next;
                }   
            
            }
            else 
            {
                if(ptail==nullptr)
                {
                    head=cur;
                    ptail = cur;
                }
                else
                {
                    ptail->next=cur;
                    ptail=ptail->next;
                }
            }
            
            cur=cur->next; 
        }
            if(newhead)
            {
                if(head)
                {
                     tail->next=head;
                     ptail->next=NULL;
                }
                
               
                return newhead;
            }
            else
            {
                if(head)
               {
                 ptail->next=NULL;
               }
               return head;
            }
       }

方法二:建立带哨兵位的头结点,避免空指针带来的麻烦

class Partition {

public:

    ListNode* partition(ListNode* pHead, int x) {

       struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));

       struct ListNode*head=(struct ListNode*)malloc(sizeof(struct ListNode));

       struct ListNode*tail=newhead;

       struct ListNode*ptail=head;

       struct ListNode*cur=pHead;

       while(cur)

        {

            if(cur->val<x)

            {

                tail->next=cur;

                tail=cur;

            }

            else 

            {

                ptail->next=cur;

                ptail=cur;

            }

        cur=cur->next;

        }

        ptail->next=NULL;

        tail->next=head->next;

       

        return newhead->next;


       }

方法:与上述反转链表题目有相似之处,反转后再一一比较,博主这里用的反转链表的方法二,建议使用方法一的三指针法从而简化代码

class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here
        struct ListNode*cur=A,*head=A;

    if(cur==NULL)

    {

        return false;

    }

    struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));

    newhead->val=head->val;

    newhead->next=NULL;

    while(cur)

    {

        struct ListNode*copy=(struct ListNode*)malloc(sizeof(struct ListNode));

        copy->val=cur->val;

        copy->next=newhead->next;

        newhead->next=copy;

        cur=cur->next;

    } 

    struct ListNode*cur2=newhead->next;
    struct ListNode*cur1=head;
    while(cur1&&cur2)
    {
        if(cur1->val==cur2->val)
        {
            cur1=cur1->next;
            cur2=cur2->next;
        }
        else 
        {
            return false;
        
        }
    }
    return true;

}

博主写这些题目花了很长时间,有很多的收获,解决这些链表题有一个好的解题思路会事半功辈,多思考一些方法对以后的解这种类似的题也会有很大的帮助,大家一起加油!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值