获取链表的中间节点乍一看和回文链表中使用快慢指针获取后半链表有点类似呢?
没错,这波操作是类似的,但也并不是完全一样,其主要思想还是快慢指针。
换句话说,如果你已理解了上面的题,那这道题也就不是什么事了。话不多说,先来分析一波。
同样我们还是定义slow慢指针每次移动一个节点,fast快指针每次移动2个节点。
那么fast快指针移动到最后节点时,slow慢指针也就是要返回的链表。
我想,你是不是有个疑问。就是为什么慢指针是移动一个节点,快节点移动2个节点?如果是偶数个节点,这个规则还正确吗!那就验证下。
为了方便,就继续上面节点的遍历。
题目中描述,如果有2个中间节点,返回第二个节点,所以返回节点【4,5,6】也就符合要求了
1.3.2 代码分析创建链表结构。
ListNode l1 = new ListNode(1); ListNode l2 = new ListNode(2); ListNode l3 = new ListNode(3); ListNode l4 = new ListNode(4); ListNode l5 = new ListNode(5); NodeFun nodeFun = new NodeFun(); nodeFun.add(l1); nodeFun.add(l2); nodeFun.add(l3); nodeFun.add(l4); ListNode head = nodeFun.add(l5);获取后半部分链表代码。
// 快慢指针 ListNode slow = head; ListNode fast = head; while(fast != null && fast.next != null){ //移动指针 fast = fast.next.next; slow = slow.next; } return slow; 1.3.3 debug调试快指针移动到节点【3】,慢指针移动到节点【2】
接着再走一步,快指针移动到节点【5】,慢节点移动到节点【3】,到此也就满足题意的要求了。
四,链表中倒数第k个节点 1.4.1 题目分析这道题要求就是返回倒数K个节点,最笨的办法就是参考上面链表反转,先将链表反转。获取前K个节点,将获取的节点再次进行反转即可得到题目要求。
但是显然这种方式只能满足答案输出,经过上面的3道题目,有没有得到什么启发呢?
是的,这道题依然可以使用双指针解决,是不是感觉双指针可以解决所有的链表问题了(QAQ)。
再仔细一想,是不是感觉和上一道《链表的中间节点》题目很类似?获取链表的中间节点是返回后半部分节点,而本道题是要求返回指定K个节点。
那就直接说结论吧,同样是定义快慢指针。只不过在上道题中快指针是每次移动2个节点,本道题中给定的K,就是快指针移动的节点个数。
同样初始化指针都在首节点,如果我们先将fast指针移动K个节点。
到此才算初始化节点完成,剩下的操作就是遍历剩下的链表,直到fast指针指向最后一个节点。
一直遍历到fast节点为null,此时返回slow指针所指引的节点。
1.4.2 代码分析初始化链表,由于和前几道题的操作是一样的,此处就不在展示。
获取倒数第K个节点的代码。
public ListNode getKthFromEnd(ListNode head, int k) { ListNode slow = head; ListNode fast = head; // 先将快指针向前移动K while (k-- > 0) { fast = fast.next; } while (fast != null) { fast = fast.next; slow = slow.next; } return slow; } 1.4.3 debug调试