day 3 day 4 第二章 链表

163 阅读3分钟

题目

203. 移除链表元素

要点:使用虚拟头节点dummy,可以用一种统一的方式处理所有节点。
注意对链表节点操作要找到 要处理的节点的前一个结点。

        ListNode dummyhead = new ListNode(0);
        dummyhead.next = head;
        ListNode cur = dummyhead;
        while(cur.next != null){
            if(cur.next.val == val){
                cur.next = cur.next.next;
            }else{
                cur = cur.next;
            }
        }
        return dummyhead.next;

707. 设计链表

都是基础操作,链表逻辑的一道很好的复习题。要点:

  1. 用size参数记录链表节点数,每次操作完记得size++或size--;
  2. 使用虚拟头节点dummy,记得链表初始化时对dummy的操作。
class MyLinkedList {
    //size存储链表元素的个数
    int size;
    //虚拟头结点
    ListNode dummy;

    //初始化链表
    public MyLinkedList() {
        size = 0;
        dummy = new ListNode(0);
    }

206. 反转链表

如果再定义一个新的链表,实现链表元素的反转,其实这是对内存空间的浪费。
其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。

方法1.双指针 从前往后翻转指针指向
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。从前往后遍历链表改变指针指向,最后返回pre;

        ListNode prev = null;
        ListNode cur = head;
        ListNode temp = null;
        while (cur != null) {
            temp = cur.next;// 保存下一个节点
            cur.next = prev;
            prev = cur;
            cur = temp;
        }
        return prev;

方法2. 根据双指针方法的递归从前往后翻转指针指向

方法3. 递归从后往前翻转指针指向

    ListNode* reverseList(ListNode* head) {
        // 边缘条件判断
        if(head == NULL) return NULL;
        if (head->next == NULL) return head;
        
        // 递归调用,翻转第二个节点开始往后的链表
        ListNode *last = reverseList(head->next);
        // 翻转头节点与第二个节点的指向
        head->next->next = head;
        // 此时的 head 节点为尾节点,next 需要指向 NULL
        head->next = NULL;
        return last;
    }

24. 两两交换链表中的节点

方法1.使用虚拟头节点,指向每次操作的两个节点的前一个节点,从前往后遍历。

方法2.递归

19. 删除链表的倒数第N个节点

快慢指针

要点:

  1. 使用虚拟头结点,这样方便处理删除实际头结点的逻辑
  2. fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作)

160.链表相交

题目数据 保证 整个链式结构中不存在环。
很简单,先求长度差,长的表先走差值个节点,然后两表一起走,直到节点相等。

## 142.环形链表II

偏数学一些,

image.png 1.先通过快慢指针找到相遇节点meet,(从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。)相交点一定在环内;
2.head 和 meet同步走,到相遇时即为入口节点。

总结

递归问题

解递归题的三部曲

  1. 找整个递归的终止条件:递归应该在什么时候结束?
  2. 找返回值:应该给上一级返回什么信息?
  3. 本级递归应该做什么:在这一级递归中,应该完成什么任务?

相关链接1
相关链接2