Leetcode日记:19&24&84.链表相关操作

Leetcode日记:19&24&84.链表相关操作

19.删除倒数第N个元素

19-题目

Given a linked list, remove the n-th node from the end of list and return its head.

Example:

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.

19-题目分析

首先,题目要求删除链表中倒数第n个元素。
其实很简单,我们只需要遍历一遍链表,知道链表的元素个数。再次遍历,找到length-n个元素就可以了。
但是题目有进阶要求,能不能只遍历一次?

答案是肯定的。请看下面代码:

19-代码

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode start = new ListNode(0);
    ListNode slow = start, fast = start;
    slow.next = head;
    //Move fast in front so that the gap between slow and fast becomes n
    for(int i=1; i<=n+1; i++)   {
        fast = fast.next;
    }
    //Move fast to the end, maintaining the gap
    while(fast != null) {
        slow = slow.next;
        fast = fast.next;
    }
    //Skip the desired node
    slow.next = slow.next.next;
    return start.next;
}

19-代码分析

这里用到了一个很巧妙的方法,我将它命名为“双指针分离法”,主要思想就是先让这两个指针岔开n个元素,然后两个指针同时向前步进。当前面的元素到最后时,后面那个元素刚好指向倒数第n个元素。
算法示意图:


leetcode19.png

24.成对交换节点

24-题目

Given a linked list, swap every two adjacent nodes and return its head.

You may not modify the values in the list's nodes, only nodes itself may be changed.

Example:

Given 1->2->3->4, you should return the list as 2->1->4->3.

24-题目分析

结点交换,是链表中老生常谈的一个话题,看似简单,编写程序的时候,容易被节点绕晕,那么我们就看看这个程序时如何编写的吧!

24-代码

public ListNode swapPairs(ListNode head) {
    if ((head == null)||(head.next == null))
        return head;
    ListNode n = head.next;
    head.next = swapPairs(head.next.next);
    n.next = head;
    return n;
}

24-代码分析

这里采用了递归,是因为如果从前往后交换的话,前面一对链接的一定要是已经交换好的下一对,所以程序的运行顺序是先将最后的交换好,然后逐渐往回过渡。

leetcode24.jpg

如图所示,每一层递归,我们都会创建new一个新节点,这个节点首先保存为head.next的信息,然后进行递归,递归返回输入链表的交换后的头节点,随后将返回的头节点设置为head.next。最后,将n.next指向head完成交换,此时原来的head.next完全被隔离,被系统回收。

这道题看似容易,实际上还是需要一番思考的。

82.删除链表重复元素II

82-题目

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

Example 1:

Input: 1->2->3->3->4->4->5
Output: 1->2->5

Example 2:

Input: 1->1->1->2->3
Output: 2->3

82-题目分析

之前有一道题是保留一个重复元素,删除多余的,那道题比较简单,这道题的意图是:只要是重复的元素,都删除,一个不留。
这就牵扯到,你要有两个指针,一个指针用于记录上一个不重复元素,另一个指针负责向前步进检测并删除重复元素。

82-代码

public ListNode deleteDuplicates(ListNode head) {
    if(head==null) return null;
    ListNode FakeHead=new ListNode(0);
    FakeHead.next=head;
    ListNode pre=FakeHead;
    ListNode cur=head;
    while(cur!=null){
        while(cur.next!=null&&cur.val==cur.next.val){
            cur=cur.next;
        }
        if(pre.next==cur){
            pre=pre.next;
        }
        else{
            pre.next=cur.next;
        }
        cur=cur.next;
    }
    return FakeHead.next;
}

82-代码分析

从代码中我们可以看出,代码用了两个指针,第一个指针pre用来记录最后一个不重复的指针(这个指针一定不会被删除掉)。第二个指针cur用来记录当前位置,用它来判断是否该元素为重复元素(cur.next!=null&&cur.val==cur.next.val),利用一个循环,直接找到下一个出现的不重复元素,这里有两种情况,一种是循环没有被执行(即cur为一个不重复元素),那么cur没有移动,我们让pre=pre.next,来更新最后一个不重复元素。如果是重复元素,则跨过cur,执行pre.next=cur.next。

链表问题总结

链表问题在所有数据结构里面所示较为简单的一种。而且相对来说问题的变数比较少,我们着重关注以下几个问题

  1. dummy哑节点

    我们可以看到,上面题目中,第一题的
    ListNode start = new ListNode(0);
    最后一道题的
    ListNode FakeHead=new ListNode(0);
    都首先创建了一个新节点,这个结点的下一个往往是输入的头节点,为什么会这么设置呢?
    哑节点设置的主要原因:
    避免头节点可能由于某种原因被删除等一系列问题而导致的边界问题,简化代码。

  2. 双指针设计

    链表的很多问题用双指针都会降低一些时间复杂度。比如leetcode24等很多问题可以应用在很多场景中:

    还有更多应用,但是思想都是不变的,指针一快一慢,具体快多少,看题目中具体要求。这便是著名的“快慢指针

更多关于链表的问题

更多关于回溯算法的问题请转到链表标签

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容

  • 什么是数组? 数组简单来说就是将所有的数据排成一排存放在系统分配的一个内存块上,通过使用特定元素的索引作为数组的下...
    启明_b56f阅读 898评论 0 0
  • 搞懂单链表常见面试题 Hello 继上次的 搞懂基本排序算法,这个一星期,我总结了,我所学习和思考的单链表基础知识...
    醒着的码者阅读 4,582评论 1 45
  • 有头链表(注意:头结点有的地方是全局变量) 初学者学自于大话数据结构,不足及错误的地方请读者提出来,谢谢。 可加 ...
    lxr_阅读 796评论 0 2
  • 2018.09.21精进打卡 姓名,朱燕平 常州新日催化剂有限公司 【日精进打卡第51天】 【知~学习】 《六项精...
    ybzyp阅读 114评论 0 0
  • 三人行,必有我师。在学校,每位同学都有闪光点,而这些闪光点都值得学习,也可以是大人的借鉴,他们在某方面都可以成为我...
    Angelina艳香阅读 273评论 0 0