剑指 Offer 22. 链表中倒数第k个节点
class Solution { public ListNode getKthFromEnd(ListNode head, int k) { LinkedList<ListNode> stack = new LinkedList<>(); // 把整个链表入栈 while (head != null) { stack.push(head); head = head.next; } // 先将前n-1个元素出栈 for (int i = 1; i < k; i++) { stack.pop(); } // 此时位于栈顶的就是倒数第k个元素啦 return stack.pop(); } }1
class Solution { ListNode res; // 代表当前处于倒数第几个节点 int cur = 0; public ListNode getKthFromEnd(ListNode head, int k) { dfs(head, k); return res; } public void dfs(ListNode node, int k) { // 先递归到末尾 if (node == null) { return; } dfs(node.next, k); // 倒数第cur个节点 cur++; // 等于k代表找到了 if (cur == k) { res = node; } } }
fast
快指针和slow
慢指针两个指针:让快指针fast
先走k
步,然后再让两个指针同时移动,等快指针fast
走道链表末尾时候(为null
),此时慢指针slow
所指向的节点就是倒数第k
个节点class Solution { public ListNode getKthFromEnd(ListNode head, int k) { ListNode fast = head; ListNode slow = head; // 让快指针先走k步,和慢指针相差k个距离 for (int i = k; i > 0; i--) { fast = fast.next; } // 此时让慢指针和快指针同时走,知道快指针到达链表末尾为null时,慢指针就在倒数第k个位置上了 while (fast != null) { fast = fast.next; slow = slow.next; } // 直接返回慢指针即为答案 return slow; } }
倒数第k个节点
等于 链表总长度-k+1
。但是在题目中我们已经指向了链表的第一个节点,所以只需要再走n-k
个节点即可到达倒数第k个节点class Solution { public ListNode getKthFromEnd(ListNode head, int k) { int length = 0; ListNode p = head; // 先获取链表的总长度 while (p != null) { p = p.next; length++; } // 其实倒数第k个的位置就相当于 length-k // 然后我们从链表头部开始遍历 length-k 个节点,此时所在的节点位置就是答案了 k = length - k; for (int i = k; i > 0; i--) { head = head.next; } return head; } }