首页 >> 大全

day4 两两交换链表中的节点(24)删除链表倒数第n个节点(19)环形链表(1

2023-11-18 大全 30 作者:考证青年

一、两两交换链表中的节点

要求:两两交换相邻节点,返回交换之后的链表

public class Test1 {static class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public static ListNode swapPairs(ListNode head) {ListNode dummyNode = new ListNode(0);dummyNode.next = head;ListNode prev = dummyNode;while (prev.next != null && prev.next.next != null) {ListNode temp = head.next.next; // 缓存 nextprev.next = head.next;          // 将 prev 的 next 改为 head 的 nexthead.next.next = head;          // 将 head.next(prev.next) 的next,指向 headhead.next = temp;               // 将head 的 next 接上缓存的tempprev = head;                    // 步进1位head = head.next;               // 步进1位}return dummyNode.next;}public static void main(String[] args) {ListNode head = new ListNode(1);ListNode node2 = new ListNode(2);ListNode node3 = new ListNode(3);ListNode node4 = new ListNode(4);head.next = node2;node2.next = node3;node3.next = node4;swapPairs(head);}

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

要求:给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

思路:使用双指针,快慢指针,首先快指针走n+1步,然后两个一块移动,直到fast指向为空,然后slow.next指向下一个节点

public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dumm = new ListNode(0);dumm.next = head;ListNode fast = dumm;ListNode slow = dumm;for(int i = 0;i

注:注意java里的栈和堆的分布,以及是否创建新的实例

三、环形链表

要求:给定一个链表,返回链表开始入环的第一个节点。如果链表无环,则返回null

解法:快慢指针,分别定义fast和slow指针,从头结点出发,fast每次移动两个节点,slow每次移动一个节点,若是在途中相遇,说明链表有环

假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。

那么相遇时: slow指针走过的节点数为:x + y, fast指针走过的节点数:x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A。

因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2:

(x + y) * 2 = x + y + n (y + z)

两边消掉一个(x+y):x + y = n (y + z)

x = (n - 1) (y + z) + z

因为要找环形的入口,那么要求的是x,因为x表示 头结点到 环形入口节点的的距离。

当n=1时,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。

n>1,fast指针在环形转n圈之后才遇到slow

在推理过程中,大家可能有一个疑问就是:为什么第一次在环中相遇,slow的 步数 是 x+y 而不是 x + 若干环的长度 + y 呢?

即文章链表:环找到了,那入口呢?(opens new )中如下的地方:

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

首先slow进环的时候,fast一定是先进环来了。

如果slow进环入口,fast也在环入口,那么把这个环展开成直线,就是如下图的样子:

可以看出如果slow 和 fast同时在环入口开始走,一定会在环入口3相遇,slow走了一圈,fast走了两圈。

重点来了,slow进环的时候,fast一定是在环的任意一个位置,如图:

那么fast指针走到环入口3的时候,已经走了k + n 个节点,slow相应的应该走了(k + n) / 2 个节点。

因为k是小于n的(图中可以看出),所以(k + n) / 2 一定小于n。

也就是说slow一定没有走到环入口3,而fast已经到环入口3了。

这说明什么呢?

在slow开始走的那一环已经和fast相遇了。

那有同学又说了,为什么fast不能跳过去呢? 在刚刚已经说过一次了,fast相对于slow是一次移动一个节点,所以不可能跳过去。

public class Solution {public ListNode detectCycle(ListNode head) {ListNode slow = head;ListNode fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast) {// 有环ListNode index1 = fast;ListNode index2 = head;// 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口while (index1 != index2) {index1 = index1.next;index2 = index2.next;}return index1;}}return null;}
}

注:文章中的图片来源于代码随想录,可以去他们的网站看看。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了