赞
踩
https://leetcode.cn/problems/kth-node-from-end-of-list-lcci/description/
实现一种算法,找出单向链表中倒数第
k
k
k 个节点。返回该节点的值。
注意:本题相对原题稍作改动
示例:
输入: 1->2->3->4->5 和 k = 2
输出: 4
说明:给定的 k k k 保证是有效的。
又是鏈結串列題(鏈表),拿到題之後我第一次的想法是先找到尾節點 tail
,遍歷找到之後發現這是個單鏈表根本就沒有前驅……
然後我思考了一下,想到了
「統計鏈表長度」
「統計鏈表長度」
「統計鏈表長度」 的解法。
可以先遍歷鏈表統計出鏈表結點個數,將鏈表長度記爲
N
N
N,然後再用給定的
k
k
k 與之相減,得到的值 (
s
t
e
p
step
step) 就是抵達欲返回的結點的步數:
s
t
e
p
=
N
−
k
step = N - k
step=N−k
然後只需要循環走
s
t
e
p
step
step 步,即可找到倒數第
k
k
k 個結點了。
程式如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: int kthToLast(ListNode* head, int k) { int count = 0; struct ListNode* cur = head; // 遍歷鏈表 while (cur->next != nullptr) { count++; cur = cur->next; } int n = count - k; // 計算第幾個 cur = head; while (n >= 0) { cur = cur->next; n--; } return cur->val; } };
當然這裏可以使用更高級的 「快慢指標法」 「快慢指標法」 「快慢指標法」,可以省掉統計鏈表長度的過程。具體方法如下:
fast
和慢指標 slow
,並初始化為 head
。fast
先走
k
k
k 步,此時 fast 和 slow 的距離差為
k
k
k。fast
碰到 nullptr
爲止。循環結束後,神奇的一幕發生了(其實一點都不神奇),slow
指向的就就是「倒数第
k
k
k 個結點」了,返回 slow
即可。
程式如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: int kthToLast(ListNode* head, int k) { struct ListNode* fast = head; struct ListNode* slow = head; // 快指標先走 for (int i = 0; i < k; i++) { fast = fast->next; } // 快慢指標一起走 while (fast != nullptr) { fast = fast->next; slow = slow->next; } return slow->val; } };
時間複雜度為 O ( n ) O(n) O(n),其中 n n n 為鏈表長度。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。