zoukankan      html  css  js  c++  java
  • 删除链表的倒数第N个节点

    给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.

    当删除了倒数第二个节点后,链表变为 1->2->3->5.

    方法一:

    希望是O(N)的算法,通过一次遍历来解决问题.

    首先题目中说了,要删除的是倒数第N个节点,那我就可以想成,他希望删除的是正数第count-N+1个节点,

    接着通过在对链表进行遍历的时候计数就可以解决该问题,我们已经知道希望删除的是正数的第count-N+1个节点

    那我们在遍历到正数的第count-N个节点时,停下来,就可以将第count-N+1个节点删除,并修复链表的节点关系

    只是需要对删除正数的第一个节点做一下特殊的处理即可。

    代码实现:
     struct ListNode {
        int val;
       struct ListNode *next;
     };
     
     struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
        int count=0;
        struct ListNode * head_ptr=head;
        while(head_ptr !=NULL){

    //先通过一次遍历得到链表中有多少个节点
            head_ptr=head_ptr->next;
            count++;
        }
        
        int num_from_top=count-n+1;  // delete node num;

    //得到从正这数,应该删除的是第几个节点
        head_ptr=head;  
        if(num_from_top == 1){

    //将删除头结点的情况单独拿出来处理
            struct ListNode * ptr=head_ptr;
            head_ptr=head_ptr->next;
            free(ptr);
            goto end;
        }

        int num=1;
        struct ListNode *cur_ptr=head; //让当前指针指向头结点

        while(cur_ptr!=NULL){

    // 开始循环遍历链表
            if(num == num_from_top-1){ // node before the one  which will be deleted;

    //找到需要删除的节点的前一个节点的时候,停止遍历,此时next指针就是需要删除的节点
                   struct ListNode * del_node =cur_ptr->next;

         cur_ptr->next=del_node->next;
                    free(del_node);
                   goto end;
            }else{
                cur_ptr=next_ptr;
                num++;
            }
        }

    end:
        return   head_ptr;
    }

    方法二:

    使用双指针的方法,整体思路是让前面的指针先移动n步,之后前后指针共同移动直到前面的指针到尾部为止。

    首先创建了一个哨兵节点sentinel, sentinel->next指向传入的head节点,然后声明两个指针变量  start 与end

    使他们都指向哨兵节点

    先让start移动N下,然后接着在开始让start与end节点同时移动,当start到了结尾的NULL的时候,此时end节点刚好在需要删除的位置处

    但是该题要求删除倒数第N个位置的节点,所以我们控制循环的条件,让start移动到最后一个节点即可,在例子中也就是5的位置,此时end节点应该在

    3的位置,恰好就是需要删除的那个节点之前的位置,操作指针,删除节点,修复链表即可

    最后将sentinel-next指向的节点返回即可。

    以下的代码中,给大家了一个main函数,便于测试与调试用。

    代码如下:

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

    struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
            struct ListNode * sentinel = malloc(sizeof(struct ListNode));
            sentinel->next=head;
            struct ListNode *ret_head=NULL;
            struct ListNode * start , *end;
            start=end=sentinel;
            while(n!=0){
                    start=start->next;
                    n--;
            }

            while(start->next!=NULL){
                    start=start->next;
                    end=end->next;
            }
            struct ListNode *del_node=end->next;
            end->next=end->next->next;
            free(del_node);
            ret_head=sentinel->next;
            free(sentinel);
            return ret_head;
    }

    int main(){
        int nums[]={1,2,3,4,5};
        int n=2;
        struct  ListNode * head=NULL;
        struct  ListNode * tail=NULL;
        int nums_num=sizeof(nums)/sizeof(int);
        int ii=0;
        for(;ii<nums_num;ii++){
            struct ListNode *  ptr=malloc(sizeof(struct ListNode));
            ptr->next=NULL;
            ptr->val=nums[ii];
            if(!head){
                tail=head=ptr;
            }else{
                tail->next=ptr;
                tail=ptr;
            }
        }

        struct ListNode * ret_list=removeNthFromEnd(head, n);
        while(ret_list !=NULL){
            printf("%d->", ret_list->val);
            struct ListNode * ptr=ret_list;
            ret_list=ret_list->next;
            free(ptr);
        }
        
    }


    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 相关阅读:
    css中的display以及position属性
    有人退税近4000元!个税年度汇算开始了,看看你能退多少?
    多维竞争
    阿里智能化接口测试平台--暴雪
    盗版网课有多猖狂?原价上万,只卖5元
    测试找BUG总结
    女程序员做了个梦。。。
    混沌的市场里,怎么一眼识别出「好房子」
    知乎扎心高赞:30岁还没有走到管理岗的人,后来怎么样了?
    自动化是在敏捷中提供连续测试的唯一方法
  • 原文地址:https://www.cnblogs.com/pigdragon/p/12445513.html
Copyright © 2011-2022 走看看