每周一道算法题(十五)

本周的题目难度级别是‘Medium’

题目:给定一串链表和一个整数n,要求删除链表倒数第n个节点

注:输入的n永远是合法的,试着访问‘一次‘链表就搞定。
其实这道题如果不限制遍历次数,难度级别也就成了EASY,就是因为只能遍历’一次‘,所以难度级别也就上升了。

说下思路,这道题最大的问题就是不知道链表长度,如果知道链表长度,那就很简单了,但是换个想法,正数和倒数的数字其实是和长度有关系的。我们定义两个指针来遍历链表,快的指针先走n-1步,然后快慢指针一起走,当快的指针走到最后一个,慢的指针就走到了倒数第n个节点,然后删除即可。
顺便拓展一下,如何找出中间的节点呢,一样的定义快慢两个指针,慢指针一次走一步,快指针一次走两步,当快指针走到最后,慢指针就走到中间了。同理,如果快指针一次走三步,那走到最后,慢指针就停留在1/3的节点处。
搞定了思路,下面来看看代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    //如果链表只有一个头节点,那么直接返回即可,因为题目说了n一定合法
    if (head->next == NULL) return head;
    //定义三个指针,都指向头结点
    struct ListNode *fast = head;
    struct ListNode *slow = head;
    struct ListNode *pre = head;
    //快指针先走n步
    while(--n && fast->next != NULL) fast = fast->next;
    //快慢指针一起走
    while (fast->next != NULL){
        fast = fast->next;
        //记录慢指针的前一个节点pre
        pre = slow;
        slow = slow->next;
    }
    //如果删除的是投节点,直接返回头节点的下一个节点
    if (slow == head) return head->next;
    //如果删除的是最后一个节点,则pre节点的下一个节点置为0,否则指向慢指针的下一个节点
    pre->next = slow->next == NULL ? 0 : slow->next;
    return head;
}

版权声明:本文为 Crazy Steven 原创出品,欢迎转载,转载时请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 链表 链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,...
    Mr希灵阅读 5,316评论 0 20
  • 本来以为一篇就能写完的,后来又感觉一篇多了一些,所以关于链表的简单算法题有加了个续篇,和上一篇一样,难度不会太大。...
    zero_sr阅读 3,552评论 0 4
  • //leetcode中还有花样链表题,这里几个例子,冰山一角 求单链表中结点的个数----时间复杂度O(n)这是最...
    暗黑破坏球嘿哈阅读 5,418评论 0 6
  • 链表问题是面试过程中经常被问到的一部分,很考查编程功底。最近刷了 LeetCode 上链表部分的面试题,我总结了一...
    JohnnyShieh阅读 10,396评论 0 9
  • 死生之事较寻常景色更触动心灵,由此,挽歌天然的具备深刻肃穆之气质,凡佳作,无不令人扼腕击节。 其一 《挽歌为沃尔夫...
    食蛙则瘦阅读 2,732评论 0 0