您的位置:首页 > Web前端 > Node.js

leecode 解题总结:19 Remove Nth Node From End of List

2017-01-31 12:25 761 查看
#include <iostream>
#include <stdio.h>

using namespace std;
/*
问题:
Given a linked list, remove the nth node from the end of list and return its head.

For example,

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.

分析:
这个是删除链表倒数第n个结点。
主要的思路:
此题的思路:设定两个指针p1,p2;其中p1先走,然后p1,p2一起走,当p1走完,此时p2恰好走到倒数第k个结点,假设链表总长度为n
注意倒数第k个结点=n-k+1,例如n=6,倒数第2个结点,实际上是第5个结点
p1先走:k-1步,然后p1,p2一起走
p1:k	,	p2:1
p1:k+1,		p2:2
...
p2:n,		p2:n-k+1(刚好是倒数第k个结点)

1 这是删除倒数第n个结点,直接找到倒数第n-1个结点,将倒数第n-1个结点的数据拷贝到第n个结点中,删除第n+1个结点
2 如果删除的倒数第1个结点,即链表末尾结点,直接遍历到最后一个结点删除

输入:
5(链表结点个数) 2(倒数第k个结点)
1 2 3 4 5

1 1
1

2 1
1 2

2 2
1 2
输出:
1 2 3 5
空
1
2

关键:
1 删除首个结点和末尾结点 + 寻找倒数第n个结点的双指针算法 + 删除指定结点用其后面结点替代
*/

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

class Solution {
public:
//看这个链表,似乎应该是头结点就存放数据了
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(NULL == head)
{
return NULL;
}
//判断n必须在1~链表结点个数之间
int nodeNum  = 0;
ListNode* tailNode = head;
ListNode* previousTailNode = NULL;
//如果当前结点下一个结点为空,那么
while(tailNode->next)
{
nodeNum++;
previousTailNode = tailNode;
tailNode = tailNode->next;
}
nodeNum++;//这里漏了最后一个指针
//参数不符合
if(n < 1 || n > nodeNum)
{
return NULL;
}
//判断如果删除的是倒数第1个结点,就直接遍历删除(需要找到其前面的一个结点)
if(1 == n)
{
//如果虽然删除的是尾结点,但是只有1个结点,则必须将头结点置空
if(1 == nodeNum)
{
delete head;
head = NULL;
return NULL;
}
else
{
previousTailNode->next = NULL;
return head;
}
}
//如果删除的是首结点,需要找到首结点的下一个结点
if(n == nodeNum)
{
//如果只有一个结点
if(1 == nodeNum)
{
delete head;
head = NULL;
return NULL;
}
//如果不止一个结点
else
{
ListNode* nextNode = head->next;
delete head;
head = nextNode;
return head;
}
}
//设定两个指针:p1先走n步,然后p1,p2一起走
ListNode* node1 = head;
ListNode* node2 = head;
for(int i = 0 ; i < n ; i++)
{
node1 = node1->next;
}
ListNode* previousNode = NULL;
while(node1)
{
node1 = node1->next;
previousNode = node2;
node2 = node2->next;
}
//找到倒数第n个结点后,需要找到倒数第n-1个结点,即node2下一个结点,将node2下一个结点数据拷贝到node2中,然后删除node2
ListNode* nextNode = node2->next;
node2->val = nextNode->val;
previousNode->next = nextNode;
delete node2;
return head;
}
};

void releaseList(ListNode* head)
{
if(NULL == head)
{
return;
}
ListNode* node;
while(head)
{
node = head->next;
delete head;
head = node;
}
}

void print(ListNode* head)
{
if(NULL == head)
{
cout << "List is NULL" << endl;
return;
}
ListNode* tempHead = head;
while(tempHead)
{
cout << tempHead->val << " ";
tempHead = tempHead->next;
}
cout << endl;
}

void process()
{
int nodeNum;
int nTh;
Solution solution;
int value;
while(cin >> nodeNum >> nTh)
{
ListNode* head = NULL;
ListNode* tail = NULL;
for(int i = 0 ; i < nodeNum ; i++)
{
cin >> value;
//采用尾插法
if(i)
{
ListNode* node = new ListNode(value);
tail->next = node;
tail = node;
}
else
{
head = new ListNode(value);
tail = head;
}
}
head = solution.removeNthFromEnd(head , nTh);
print(head);
releaseList(head);
}
}

int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: