链表(未完待续)

文章介绍了多种基于链表的算法问题解决方案,包括移除特定值的节点、反转链表、找到链表的中间节点、找到链表中倒数第k个节点、两两交换链表节点以及删除链表的倒数第n个节点。这些方法利用了双指针或三指针技术,对链表进行高效操作。
摘要由CSDN通过智能技术生成

1.力扣203题 移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

struct ListNode* removeElements(struct ListNode* head, int val){
    if(head==NULL) return NULL;
      struct ListNode*cur=head,*prev=NULL;
      while(cur){
        if(cur->val==val){
             if(prev){//如果前置指针不为空,则正常删除,如果前置指针为空,则进行的是头删
                prev->next=cur->next;
                free(cur);
                cur=prev->next;
             }
             else{
                 cur=head->next;
                 free(head);
                 head=cur;
             }
             
        }  
        else{//如果cur的指向的节点并非所要删除的,则让两个指针都向后移动一位即可
            prev=cur;
            cur=cur->next;
        }
      }
      return head;
}

2.力扣206题 反转链表

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

采用三指针的方法,n1指向NULL,n2指向头结点,n3指向头结点的下一个结点

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

将原链表每一个元素头插
struct ListNode 用来保存cur的下一个节点,使得cur能够遍历整个原链表

3.力扣876题-链表的中间节点

struct ListNode* middleNode(struct ListNode* head){
     struct ListNode*fast=head;
     struct ListNode*slow=head;
     while(fast&&fast->next){
         fast=fast->next->next;
         slow=slow->next;
     }
     return slow;
}

让快慢指针都从头结点开始,快指针每一次都比慢指针快走一步

4.剑指offer22题-链表中倒数第k个结点

struct ListNode* getKthFromEnd(struct ListNode* head, int k){
     struct ListNode*slow=head;
     struct ListNode*fast=head;
     while(k--){
         if(fast==NULL) return NULL;
         fast=fast->next;
     }
     while(fast){
         slow=slow->next;
         fast=fast->next;
     }
     return slow;
}

让快指针先走k步(中间如果为空则直接return NULL)
之后让两个指针同时走

5.力扣24题两两交换链表中的节点

 struct ListNode* swapPairs(struct ListNode* head){
      struct ListNode*dummyhead=(struct ListNode*)malloc(sizeof(struct ListNode));
      dummyhead->next=head;
      struct ListNode*left=dummyhead;
      struct ListNode*right=dummyhead->next;
      while(left&&right&&left->next->next){
          left->next=right->next;
          right->next=left->next->next;
          left->next->next=right;
          left=right;
          right=right->next;
      }
      return dummyhead->next;
}

这里让left指向虚拟头结点,让right指向虚拟头结点的下一个,然后不断迭代

6力扣19题 删除链表的倒数第n个结点.

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
struct ListNodedummyHead=(struct ListNode)malloc(sizeof(struct ListNode));
dummyHead->next = head;
struct ListNode* slow = dummyHead;
struct ListNode* fast = dummyHead;
while(n-- && fast != NULL) {
fast = fast->next;
}
fast = fast->next; // fast再提前走一步,因为需要让slow指向删除节点的上一个节点
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return dummyHead->next;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值