代码随想录 打卡04

60 阅读2分钟

两两交换链表中的节点

leetcode 24

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

解题的关键在于需要理解清楚循环退出的条件,同时处理好每个循环中节点交换的逻辑,建议先在草稿本上画出交换的逻辑。


class Solution {
    public ListNode swapPairs(ListNode head) {

        ListNode dummyHead = new ListNode(-1, head);
        ListNode current = dummyHead;

        while(current.next != null && current.next.next != null) {
            ListNode temp1 = current.next; // 保存节点到临时变量中
            ListNode temp2 = current.next.next.next; // 保存节点到临时变量中
            current.next = current.next.next;
            current.next.next = temp1;
            current.next.next.next = temp2;

            current = current.next.next;
        }
        return dummyHead.next;
    }
}

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

leetcode 19

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

经典的快慢指针的问题,快指针走到终点的时候,慢指针刚好走到倒数第n个节点的前一个节点,方便进行节点的操作。注意也是需要设置一个dummyHead来处理原始链表的头节点。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode faster = head; 

        ListNode dummyHead = new ListNode(-1, head);
        ListNode slower = dummyHead;
        int counter = 1;
        ListNode result = slower;

        while(faster != null) {

            if(counter < n) {
                counter++;
            } else {
                if(faster.next == null) {
                    slower.next = slower.next.next;
                    break;
                }
                slower = slower.next;
            }
            faster = faster.next;
         }

         return result.next;
    }
}

面试题 02.07. 链表相交

力扣

引入了一个hashSet来解决判断是否相等的问题,好处是比较容易想到,坏处是占用了一定的内存空间

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode currentA = headA;
        ListNode currentB = headB;

        ListNode result = null;

        HashSet<ListNode> set = new HashSet<>();

        while(currentA != null) {
           set.add(currentA);
           currentA = currentA.next;
        }

        while(currentB != null) {
            if(set.contains(currentB)) {
                result = currentB;
                break;
            } else {
                currentB = currentB.next;
            }
        }
        return result;

    }
}

142.环形链表II

力扣

引入hashset这题会非常容易,如果不能引入额外的空间,就需要用其指针的方法来解决。

public class Solution {
    public ListNode detectCycle(ListNode head) {

        ListNode current = head;

        Set<ListNode> set = new HashSet<>();

        ListNode result = null;

        while(current != null) {
            if(set.contains(current.next)) {
                result = current.next;
                break;
            } else {
                set.add(current);
            }
            current = current.next;
        }
        return result;
    }
}

链表总结

链表相关的问题在写代码的时候往往并不容易,很多时候虽然知道思路,但是在实现的时候会出现很多问题。在实现的时候需要注意:

  1. 头节点的处理
  2. 循环中引用的处理,不能随意修改一个引用的指向
  3. 想清楚退出条件
  4. 注意看题目要求返回的是特殊节点还说头节点,如果是头节点,相当于就是返回处理好之后的整个链表
  5. 对于需要遍历所有元素,然后处理倒数数字的问题,可以考虑快慢指针
  6. 任何链表相关的问题最好先画出来,理清思路,再开始写代码