链表

100 阅读4分钟

移除链表元素

题目:203

  • 经典题目,思路也确实能知道,就是如果发现了要删除的值,就直接跨过该结点,指向下一个,但是代码问题......
  1. 先判断链表是否为空,要是空直接返回null
  2. 在这种问题上,总会涉及到链表头部这种麻烦的情况,所以最好弄一个虚拟结点,用于指向最后结果的头部
  3. 再定义两个指针,pre cur。cur用于探索,判断该结点是不是应该移除。pre在cur之前,用于把不该移除的结点串起来,如果cur检测到了要被移除的结点。pre.next = cur.next。循环退出条件就是cur == null

设计链表

题目:707

  • 设计类的,有点考验人如何从头做起
  • 已知,节点是链表的一个基本单位,所以得写一个结点类
class ListNode {
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val) {
        this.val=val;
    }
}  

  • 然后初始化链表。链表的两个条件:长度和头部。定义一下,然后初始化
    int size;
    //虚拟头结点
    ListNode head;

    //初始化链表
    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
    }
  • 以上条件写好,接下来的行为其实就是平时会写的链表增删改查操作,就那种删除是把节点跨过去,增加是把节点加进来。这个就自己写吧

反转链表

题目:206

  • 这个好像不用去先判定head是否为空,毕竟之后cur初始化为head,循环条件为判定cur是否为空可以涉及到
  • 也没用到空节点
  • 迭代,需要定义三个指针,pre cur temp。pre:之前 cur:现在 temp:之后
  • pre temp刚开始初始化为null cur初始化为head。以cur是否到头为循环条件,然后三个指针来回配合以达成链表的反转。 temp指向cur.next,然后cur就可以指向pre来达成一个反转,一个反转完成后,调整pre和cur的位置,再次进入循环
  • 递归就感觉有点子抽象,毕竟感觉递归都挺抽象的。这里的递归函数,其内容和迭代大差不差,看着写吧
private ListNode reverse(ListNode prev, ListNode cur)

两两交换链表中的节点

题目:24

  • 这里最好要用到哑节点,因为相邻节点,对于每一次要交换的头节点来说,好像没有前一个指针指向它......
  • 迭代:用到四个功能节点,一个辅助用节点(哑节点
  • cur:指向每一次交换部分的头结点,初始化为哑节点,指向head
  • temp:暂时存储下一个交换部分的头结点
  • firstnode:交换部分的第一个节点
  • secondnode:交换部分的第二个节点
  • 递归的话......有点抽象,不确定,再看看

删除链表的倒数第n个节点

题目:19

  • 无他,唯手熟尔。利用双指针,先提前让两个指针之间间隔n(从pre开始next n下到cur),pre 和 cur 。这样,如果cur.next为null的话,正好pre.next就是链表的倒数第n个节点,直接跳过就可以 pre.next = pre.next.next
  • 大概思路如此,然后鉴于可能头结点就被跳过,所以设一个哑节点,初始化dummy.next = head。即使最后原始头结点被跳过,但是返回的头结点仍为dummy.next

链表相交

题目:面试题02.07

  • 两个链表A B不一定相等,如果它们之间确实有交点,让出发点距离交点的长度一样即可
  • 利用A B的长度差,让长的一方先走几步,把长度差消除
  • 所以得先把两个链表遍历一遍,求出各自长度(用到新指针curA curB
  • 不知道是A长还是B长,这里可以强制让curA指向长的链表,比较长度,然后交换即可
if (lenB > lenA) {
            //1. swap (lenA, lenB);
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            //2. swap (curA, curB);
            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }
  • 然后就是利用长度差,消除长度差,然后两个指针一路next,要么有交点,发现两个指针指向一个节点。要么没节点,直接到头
  • 顺便学学人家的命名方式

环形链表

题目:142

  • 环形链表好像跟快慢指针脱离不了关系,有点像高中常见跑圈问题,在环形操场上,跑得快的总会遇上跑得慢的
  • slow和fast在开头一起出发,一个一次走一步,一个一次走两步。如果又换,两指针会相遇,此时一个返回head,一个就在此时相遇的地方。然后两指针再次同时出发,但是这次都一次走一步,再次相遇就是交点
  • 思路如上,至于怎么推导出来的,去看解析吧......问就是数学小推理