C链表part3

1
题目
在这里插入图片描述

思路
在这里插入图片描述

实现

ListNode* lesshead, *lesstail;
        ListNode* greaterhead, *greatertail;
        lesshead = lesstail = (ListNode*)malloc(sizeof(ListNode));
        greaterhead = greatertail = (ListNode*)malloc(sizeof(ListNode));
        lesshead->next = greaterhead->next = NULL;
        
        ListNode* cur = pHead;
        while(cur)
        {
            if(cur->val < x)
            {
                lesstail->next = cur;
                lesstail = lesstail->next;
            }
            else
            {
                greatertail->next = cur;
                greatertail = greatertail->next;
            }
            cur= cur->next;
            
        }
        lesstail->next = greaterhead->next;
        
        ListNode* list = lesshead->next;
        free(lesshead);
        free(greaterhead);
        return list;  

2
题目
在这里插入图片描述

思路
在这里插入图片描述

实现

/*法1:分割链表。1.将链表分为两部分(中间节点之前+中间节点之后);2.逆转后半部分链表;3.遍历两链表比较。时间复杂度O(n);空间复杂度O(1)
法2:重新创建一个新链表。保存逆置后的链表内容;然后遍历比较原链表和逆置后的链表。
*/
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here
        if(A==NULL)
            return false;
        if(A->next==NULL)
            return true;
        ListNode *slow=A;
        ListNode *quick=A;
          
        //1.找中间节点
        while(quick && quick->next)
        {
            slow=slow->next;
            quick=quick->next->next;
        }
          
        ListNode *next=slow->next;
        ListNode *prev=NULL;
        //2.逆置后半部分
        while(slow)
        {
            slow->next=prev;
            prev=slow;
            slow=next;
            if(next!=NULL)
                next=next->next;
        }
          
        //3.遍历比较两链表
        ListNode* list=A;
        ListNode* newlist=prev;
        while(newlist && list)
        {
            if(newlist->val == list->val)
            {
                newlist=newlist->next;
                list=list->next;
            }
            else
            {
                return false;
            }
        }
        return true;
    }
};

3
题目
在这里插入图片描述

思路
在这里插入图片描述

实现

typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //遍历链表
    ListNode* curA = headA;
    int la = 0;
    while(curA)
    {
        ++la;
        curA = curA->next;
    }
    ListNode* curB = headB;
    int lb = 0;
    while(curB)
    {
        ++lb;
        curB = curB->next;
    }

    //假设链表长短
    ListNode* longlist = headA;
    ListNode* shortlist = headB;
    if(lb>la)
    {
        longlist = headB;
        shortlist = headA;
    }

    //长的链表先走差值
    int gap = abs(la-lb);
    while(gap--)
    {
        longlist = longlist->next;
    }

    while(longlist)
    {
        if(longlist == shortlist)
        {
            return longlist;
        }
        longlist = longlist->next;
        shortlist = shortlist->next;
    }
    return NULL;
}

4
题目
在这里插入图片描述

思路
在这里插入图片描述

实现

bool hasCycle(struct ListNode *head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;

    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
        {
            return true;
        }
    }
    return false;
    
}

5
题目
在这里插入图片描述

思路
在这里插入图片描述

实现

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow,  *fast;
    slow = fast = head;
    while(fast && fast->next)
    {
        
        slow = slow -> next;
        fast = fast -> next -> next;

        if(fast == slow)
        break;
    }

    if(fast == NULL || fast->next == NULL)
      return NULL;
    
    struct ListNode* meet = fast;
    while(head != meet)
    {
        head = head->next;
        meet = meet->next;
    }
    return meet;
}

6
题目
在这里插入图片描述

思路
在这里插入图片描述

实现

//方法二:原位置拷贝链表
//1,遍历链表,对每个节点复制新的节点插入到当前节点后面,形成新的链表
//2,修改新复制节点的随机指针 指向 后一个节点
//3,拆分链表
struct Node* copyRandomList(struct Node* head) {

    struct Node*    pTmp    = NULL;
    struct Node*    pSrc    = NULL;
    struct Node*    pDes    = NULL;

    if(NULL == head) return NULL;

    //1,复制每个节点,并将新的节点插入每个节点后面
    pSrc = head;
    while(NULL != pSrc)
    {
        pTmp = (struct Node*)malloc(sizeof(struct Node));
        if(NULL == pTmp) return NULL;

        pTmp->val = pSrc->val;
        pTmp->random = pSrc->random;

        pTmp->next = pSrc->next;
        pSrc->next = pTmp;
        pSrc = pTmp->next;
    }
    
    //2,修改新链表中新增的节点的随机指针
    pSrc = head;
    while(NULL != pSrc)
    {
        pDes = pSrc->next;
        if(NULL != pDes->random)
        {
            pDes->random = pDes->random->next;
        }
        pSrc = pDes->next;
    }

    //3,拆分出复制好的链表
    pSrc = head;
    pDes = head->next;
    while((NULL != pSrc) && (NULL != pSrc->next))
    {
        pTmp = pSrc->next;
        pSrc->next = pTmp->next;

        pSrc = pTmp->next;
        if(NULL != pTmp->next)
        {
            pTmp->next = pSrc->next;
        }
    }
    return pDes;
}

作者:r0vHWU5AdJ
链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer/solution/chun-clian-biao-de-shen-kao-bei-138fu-zhi-dai-sui-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


7
题目
在这里插入图片描述

思路
在这里插入图片描述

实现


typedef struct ListNode Node;
struct ListNode* insertionSortList(struct ListNode* head){
    if(head == NULL || head -> next == NULL)
       return head;
    Node* sorthead = head;
    Node* cur = head->next;
    sorthead->next = NULL;
    while(cur)
    {
        Node* next = cur->next;

        //把cur插入到sorthead链表中并保持有序
        if(cur->val <= sorthead->val)
        {
            //头插
            cur->next = sorthead;
            sorthead = cur;
        }
        else
        {
            //中间结点
            Node* sortPrev = sorthead;
            Node* sortcur = sortPrev->next;

            while(sortcur)
            {
                if(cur->val <= sortcur->val)
                {
                    sortPrev->next = cur;
                    cur->next = sortcur;
                    break;
                }
                else
                {
                    sortPrev = sortcur;
                    sortcur = sortcur->next;
                }
            }
            //尾插
            if(sortcur == NULL)
            {
                sortPrev->next = cur;
                cur->next = NULL;
            }

        }
        cur = next;

    }
    return sorthead;

}

8
题目
在这里插入图片描述

思路
在这里插入图片描述

实现
//来源评论

  ListNode current = pHead; //记录当前待检查的节点
        ListNode q ; //检查中的临时节点,与current进行比较,看是否是重复节点
        ListNode pre = null; //因为重复节点不保留,所以需要pre来保存上一个的不重复的节点
        boolean flag = false; //记录current是否有重复节点,有的话即为true
        while(current != null){ //当前节点不为空,则进行遍历
            flag = false;
            q = current.next; 
            
            //将当前节点与后面的节点进行比较,看是否是重复节点,并找到下一个与当前节点不相同的节点
            while(q != null && current.val == q.val){ 
                flag = true; 
                q = q.next;
            }
            
            if(flag){ //若当前节点是重复节点,并判断是否是头结点
                if(current.val == pHead.val){//若是头结点,则令头结点为后面第一个不重复的节点,pre仍不变
                    pHead = q;
                }else{
                    pre.next = q; //若不是,则令pre的下一个节点指向该q,下一步就是判断q是否是重复节点
                }
            }else{
                pre = current; //pre保存的节点肯定是判定为 没有重复的节点
            }
            current = q; //进行下一个节点的判断
        }
        return pHead;
    };


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值