題目
給定一個鏈表,刪除鏈表的倒數第 個節點,並且返回鏈表的頭結點。
示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.
函數原型
C
的函數原型:
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
}
邊界判斷
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
}
算法設計:從前掃一遍,從後掃一遍
思路:先計算鏈表長度(從前掃一遍),再刪除倒數第 n 個結點(從後掃一遍)。
typedef struct ListNode Node;
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
// 設置一個虛擬頭節點(哨兵)
Node* H = malloc(sizeof(Node));
H->next = head;
// 兩個指針跟隨用於刪除
Node*p = H->next, *pre = H;
int cnt = 1;
int i = 1;
while(p){
p = p->next;
cnt++; // 計算length
}
p = H->next; // 把p拉回去
while(i<(cnt-n) ){
pre = p;
p = p->next;
i++;
}
// 循環結束,pre位於要刪除節點的前驅,p在刪除位置
pre->next = p->next;
free(p);
// 釋放哨兵
Node *ans = H->next;
free(H), H = NULL;
return ans;
}
- 時間複雜度:
- 空間複雜度:
算法設計:雙指針
思路:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/chao-jian-ji-shuang-zhi-zhen-fu-tu-jie-by-newpp/
配套編碼:
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
struct ListNode *p = head, *q = head;
while(p){
if(n < 0){
q = q -> next;
}
n--;
p = p -> next;
}
if(n == 0){
return head -> next;
}
q -> next = q -> next -> next;
return head;
}
- 時間複雜度:
- 空間複雜度:
算法設計:遞歸
思路:m從後開始統計元素個數,如果等於n,即到達倒數第n個,將當前下一節點指向返回個當前上一節點連接,否則返回當前節點連接 遞歸回溯,來回一次。
int m;
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
if( head == NULL ){
m = 0;
return head;
}
head->next = removeNthFromEnd(head->next, n);
return ++m==n ? head->next : head;
}
- 時間複雜度:
- 空間複雜度: