圖解鏈表中倒數第k個節點

輸入一個鏈表,輸出該鏈表中倒數第k個節點。爲了符合大多數人的習慣,本題從1開始計數,即鏈表的尾節點是倒數第1個節點。例如,一個鏈表有6個節點,從頭節點開始,它們的值依次是1、2、3、4、5、6。這個鏈表的倒數第3個節點是值爲4的節點。

示例:

給定一個鏈表: 1->2->3->4->5, 和 k = 2.

返回鏈表 4->5.

解題思路:

  • 第一時間想到的解法:
    先遍歷統計鏈表長度,記爲 n ;
  • 設置一個指針走 (n-k) 步,即可找到鏈表倒數第 k 個節點。
    使用雙指針則可以不用統計鏈表長度。
    在這裏插入圖片描述

算法流程:

  1. 初始化: 前指針 former 、後指針 latter ,雙指針都指向頭節點 head​ 。
  2. 構建雙指針距離: 前指針 former 先向前走 k 步(結束後,雙指針 former 和 latter 間相距 k 步)。
  3. 雙指針共同移動: 循環中,雙指針 former 和 latter 每輪都向前走一步,直至 former 走過鏈表尾節點時跳出(跳出後, latter 與尾節點距離爲 k-1,即 latter 指向倒數第 k 個節點)。
  4. 返回值: 返回 latter 即可。
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    複雜度分析:
    時間複雜度 O(N): N爲鏈表長度;總體看, former 走了N步, latter 走了 (N-k)步。
    空間複雜度 O(1): 雙指針 former , latter 使用常數大小的額外空間。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
           ListNode* former = head;
           ListNode* latter = head;
           while(k)
           {
               former = former->next;
               k--;
           } 
           while(former)
           {
               latter = latter->next;
               former = former->next;
           }
           return latter;
    }
};

在這裏插入圖片描述

class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
           if(head == NULL || k == 0) 
            {
            	return NULL;
            }
           ListNode* former = head;
           ListNode* latter = head; 
           int i = 0;
           while(former)
           {
           	   if(i>=k)
           	   {
           	   		latter = latter->next;
           	   }
               former = former->next;
               i++;
           } 
           return latter;
    }
};

在這裏插入圖片描述
參考
https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章