1. 程式人生 > >刪除鏈表的倒數第N個節點(三種方法實現)

刪除鏈表的倒數第N個節點(三種方法實現)

from ++ n+1 while end != bsp -- 結點

刪除鏈表的倒數第N個節點

給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。

示例:

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

當刪除了倒數第二個節點後,鏈表變為 1->2->3->5.

說明:

給定的 n 保證是有效的。

方法一解題思路:要求刪除倒數第N個節點,可以先設兩個指針同時指向鏈表的第一個節點,一個指針遍歷鏈表統計出總共有多少個節點記為i,用總數減去N,即可以算出要刪除的節點為正數第幾個節點記為index=i-N,讓另一個指針移動到index節點的前一個節點(如果要刪除的節點不是第一個節點)。最後執行刪除操作,如果要刪除的節點為第一個節點,則需要修改頭指針,反之,則直接刪除即可

/*解法一*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
int i = 1, j = i, index = 0;
struct ListNode *p, *ptr;
p = ptr = head;

/*尋找到尾節點*/
while (p->next != NULL)
{
p = p->next;
i++;
}

/*確定要刪除的節點為正數第幾個節點*/
index = i - n + 1;

/*將另一個指針移動到index節點的前一個位置*/
while (j + 1 < index)
{
ptr = ptr->next;
j++;
}
/*刪除操作,判斷要刪除的節點是否為第一個節點*/
if (index != 1)
{
ptr->next = ptr->next->next;
return head;
}
else
{

return head = ptr->next;
}
}

方法二解題思路:設置兩個指針同時指向第一個節點,讓第一個指針p向前移動n次,之後第二個指針p和指針ptr開始一起移動,直到p為空或者p->next為空,此時指針ptr指向要刪除節點的前一個節點(如果要刪除的不是第一個節點)。如果要刪除的節點為第一個節點,則需要修改頭指針,反之則直接刪除即可。

/*解法二*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode *p, *ptr = p = head;
int i;

/*讓指針p向前走n步*/
while (n-- > 0)
{
p = p->next;
}

/*當指針p走完n步以後,讓指針p和ptr同時向前走,直到p走到最後一個節點,即p->next=NULL,整個過程p和ptr之間相隔n-1個節點*/
while (p&&p->next != NULL)
{
ptr = ptr->next;
p = p->next;
}

/*此時的ptr指向要刪除節點的前一個節點,需要考慮刪除的節點是否為首元節點*/
if (p == NULL)
return head = head->next;
else
{
ptr->next = ptr->next->next;
return head;
}
}

方法三解題思路:方法三和方法四大同小異,首先當front非空時,讓front移動n+1次,之後讓behind跟著front一起移動(front和behind之間相隔n-1個節點),直到front為空。移動結束以後實行刪除操作,刪除操作和方法一和方法二一樣。

struct ListNode * removeNthFromEnd(struct ListNode * head,int n){

struct ListNode* front = head;
struct ListNode* behind = head;

while (front != NULL) {
front = front->next; /*指針front往前移動n+1次*/

if (n-- < 0) behind = behind->next;  /*如果指針behind==0,表明需要刪除的節點為第一個節點*/
}

/*循環過後,兩個指針之間相隔n-1個節點*/
if (n == 0) head = head->next;
else behind->next = behind->next->next;
return head;

以上就是解題心得,如果有錯誤或有疑問歡迎大家指出,大家共同進步。

刪除鏈表的倒數第N個節點(三種方法實現)