leetcode日记04

day04


例题 leetcode 24. 两两交换链表中的节点

链接:https://leetcode.cn/problems/swap-nodes-in-pairs/

思路:模拟链表两两交换的过程就能够通过本题目,对链表的操作一般使用虚拟头节点来进行会比较好,
因为这样子不需要针对头节点单独设置特殊的情况。交换步骤如下:

重点:想到模拟交换的过程并不难,但是步骤的先后会严重影响结果。需要保证按照该步骤进行节点指针的修改!
在这里插入图片描述

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode pre = null;
        ListNode dummyhead = new ListNode();
        dummyhead.next = head;
        ListNode cur = dummyhead;
        ListNode temp1;
        ListNode temp2;
        while(cur.next != null && cur.next.next != null){
            temp1 = cur.next;
            temp2 = cur.next.next;
            ListNode temp = temp2.next;
            cur.next = temp2;
            temp2.next = temp1;
            temp1.next = temp;
            cur = temp1;
        }
        return dummyhead.next;
    }
}

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

链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/

思路:双指针法,让快指针先前进n步。之后,慢指针和快指针同时前进,那么当快指针走到链表末尾时,慢指针指向的下一个节点就是要删除的节点。

因为这样子就能够保证慢指针和链表末尾的间隔为n。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        ListNode slow = dummy;
        ListNode fast = head;
        int temp = n;
        while(temp > 0){
            fast = fast.next;
            temp--;
        }
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return dummy.next;
    }
}

例题 leetcode 面试题 02.07. 链表相交

链接:https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/

方法1:哈希表

首先遍历链表headA,并将链表headA中的每个节点加入哈希集合中。然后遍历链表headB,对于遍历到的每个节点,判断该节点是否在哈希集合中:

如果当前节点不在哈希集合中,则继续遍历下一个节点;

如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表 headB\textit{headB}headB 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> visited = new HashSet<ListNode>();
        ListNode temp = headA;
        while (temp != null) {
            visited.add(temp);
            temp = temp.next;
        }
        temp = headB;
        while (temp != null) {
            if (visited.contains(temp)) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }
}

方法2:双指针法
设a为headA总长,b为headB总长,c为两链表的公共长度(若存在)

可得,a + c != b + c,但只需让a和b走过互相走过的路,即可到达同个结点,即a + c + b == b + c + a

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        ListNode pA = headA, pB = headB;
        while (pA != pB) {
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        return pA;
    }
}
源自:leetcode官方解答

例题 leetcode 142.环形链表II

链接:https://leetcode.cn/problems/linked-list-cycle-ii/

思路:这道题目本质上就是数学题目。设置快慢指针,刚开始都位于链表的头部。slow链表每次向后移动一位的同时,fast链表每次向后移动两位。
如果链表中没有环,则fast指针最终会为null。如果有环,则如下图:
在这里插入图片描述

由题意得,fast指针走过的距离设为a + n * (b + c)+ b。且该距离始终为slow指针的2倍。由此可得,a + (n + 1) b + nc = 2 (a + b)。

即a = (n - 1)(b + c) + c -->即 a = c。

由此,当slow指针和fast指针相遇的时候,设置一个从头节点开始前进的指针和slow节点同时前进,他们相遇的位置就是入环点。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode slow = head, fast = head;
        while (fast != null) {
            slow = slow.next;
            if (fast.next != null) {
                fast = fast.next.next;
            } else {
                return null;
            }
            if (fast == slow) {
                ListNode temp = head;
                while(temp != slow){
                    temp = temp.next;
                    slow = slow.next;
                }
                return temp;
            }
        }
        return null;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值