链表 LeetCode19

题目:

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

方法一:遍历链表,获取链表长度len,删除链表第len-n+1个节点

#include "stdafx.h"
#include <iostream>
using namespace std;

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

int Getlength(ListNode* head, int n) {
	//获取链表长度
	int len = 1;
	while (head->next) {
		head = head->next;
		len++;
	}
	return len;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
	if (head == nullptr || head->next == nullptr) return  nullptr;
	ListNode*p = head;
	ListNode*q = head;
	//获取链表长度
	int len = Getlength(head, n);
	//此时删除头结点 例如[1.2] n=2
	if (len == n) {
		head = head->next;
	}
	else {
		int index = len - n - 1;
		while (index && q->next) {
			q = q->next;
			index--;
		}
		p = q->next;
		//[1,2,3,4,5]  n=2
		if (q->next->next) {
			q->next = q->next->next;
		}
		//此时删除的是下一个节点  [1,2,3]  n=1
		else {
			q->next = nullptr;
		}
	}
	delete p;
	p = nullptr;
	return head;
}

ListNode * CreateNode(int n)  //尾插法  
{
	ListNode *head = NULL, *pnew = NULL, *ptail = NULL;  //创建表头、表尾和新插入结点并初始化  
	int num, i = 1;
	while (i <= n)
	{
		pnew = new ListNode(0);
		cout << "输入第" << i << "个结点:" << endl;
		cin >> num;
		pnew->val = num;
		pnew->next = NULL;
		if (head == NULL)
			head = pnew;
		else
		{
			ptail->next = pnew;
		}
		ptail = pnew;
		i++;
	}
	pnew = NULL;
	delete pnew;
	return head;
}



int main()
{
	int n = 0, m = 0; //结点个数  
	cout << "输入结点个数:" << endl;
	cin >> n;
	ListNode *head = CreateNode(n);
	cout << "要删除的节点为倒数第:" << endl;
	cin >> m;
	ListNode *answer = removeNthFromEnd(head, m);
	return 0;
}



方法二:

使用两根指针,指针间距离为n-1.当一根指针指向链表尾节点时,证明另一根指针所指节点应该被删除。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
   ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* pNode = head;
        ListNode* fast = head;
        ListNode* slow = head;
        //使快指针移动n步,使其与慢指针之间保持一定距离
        for (int i = 0; i < n; ++i) fast = fast->next;
        if (fast == nullptr)
        {
            pNode = head->next;
            delete head; head = nullptr;
            return pNode;
        }
        //使快慢指针同步运动,直到快指针指向链表尾
        while (fast->next != nullptr)
        {
            fast = fast->next;
            slow = slow->next;
        }
        //使pNext指向该被删除的节点
        ListNode* pNext = slow->next;
        slow->next = pNext->next;
        //释放空间
        delete pNext; pNext = nullptr;
        return head;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_29996285/article/details/80230393
今日推荐