力扣单链表必刷题(1)

目录

一,反转链表(206)

二,合并两个有序列表(2)


一,反转链表(206

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

思路1:三指针法

 开始让n1指向空指针,n2指向第一个的位置,用n3标记n2下一个节点的位置,让n2的下一个节点指向n1,然后让n1指向n2所指向的地址,n2指向n3 所指向的地址,最后让n3指向下一个节点的位置(当n3指向空时就不在执行这一步)。循环执行上面的步骤,直到最后一步完成后n2指向空为止。代码如下:

struct ListNode* reverseList(struct ListNode* head){
//三指针法
    if(head == NULL)
    {
        return NULL;
    }
    struct ListNode* n1,*n2,*n3;
    n1 = NULL;
    n2 = head;
    n3 = n2->next;
    while(n2)
    {
        n2->next = n1;
        n1 = n2;
        n2 = n3;
        if(n3)
        n3=n3->next;
    }
    return n1;
}

思路二:取节点插到新链表

 开始让newhead指向NULL,cur指向头结点,用next 标记cur的下一个节点,让cur指向newhead,然后让newhead指向cur,cur向next,next指向下一个节点。循环上面步骤,当cur指向空指针停止。代码如下:

//取节点插到新链表
struct ListNode* cur = head,*newhead = NULL;
while(cur)
{
    struct ListNode *next = cur->next;
    cur->next = newhead;
    newhead = cur;
    cur = next;
}
 return newhead;

}

二,合并两个有序列表(2

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

 不带哨兵位思路:

 将两个链表依次比较,选取更小的数来尾插。这里用cur1标记第一个链表,用cur2标记第二个链表,用head当作头节点,方便返回,用tail当作尾节点,方便尾插。先将cur1指向的数与cur2比较,小的尾插到tail后面,然后刚才比较小的链表cur向后指向一位,依次重复上面的步骤,直到有一个链表结束的时候停止,第一次尾插的时候,没有哨兵位需要将cur指向的值赋值给head,tail,来当做新链表的头结点和尾节点。代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
   //不带哨兵位
    if(list1==NULL)
    {
        return list2;
    }
    if(list2==NULL)
    {
    return list1;
    }
    struct ListNode* cur1 = list1,*cur2 = list2;
    struct ListNode* head = NULL,*tail = NULL;
    while(cur1 && cur2)
    {
        if(cur1->val < cur2->val)
        {
            if(head==NULL)
            {
                head = tail = cur1; 
            }
            else
            {
                tail->next = cur1;
                tail= tail->next;
            }
             
            cur1 = cur1->next;
        }
        else{
            if(head == NULL)
            {
                head = tail = cur2;
            }
            else
            {
                tail->next = cur2;
                tail= tail->next;
            }
           
            cur2 = cur2->next;
        }

    }
        if(cur1)
        {
            tail->next = cur1;
        }
        if(cur2)
        {
            tail->next = cur2;
        }
    return head;
    }

带哨兵位的思路:

 思路与上面相同,只是这里创建了一个哨兵位来作为头结点,不存储数据,只负责“站岗”。最后用完需要将哨兵位free掉。代码如下:

   /**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


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

    }
        if(cur1)
        {
            tail->next = cur1;
        }
        if(cur2)
        {
            tail->next = cur2;
        }
        struct ListNode*head = guard->next;
        free(guard);
       
    return head;


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会背雨霖铃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值