删除给定链表末尾的第 N 个节点
给定一个链表和一个整数 N,任务是删除给定链表末尾的第 N 个节点。
例子:
输入:2 -> 3 -> 1 -> 7 -> NULL,N = 1
输出:
创建的链表为:
2 3 1 7
删除后的链表为:
2 3 1
输入:1 -> 2 -> 3 -> 4 -> NULL,N = 4
输出:
创建的链表为:
1 2 3 4
删除后的链表为:
2 3 4
设 K 为链表中的总节点数。
观察:从末尾算起的第 N 个节点是从开头算起的第 (K-N+1) 个节点。
所以问题就简化为我们必须从头开始找到第 (K-N+1) 个节点。
- 一种方法是在一次遍历中找到链表的长度 (K),然后在第二次遍历中从头开始移动 (K-N+1) 步,到达从末尾算起的第 N 个节点。
C++
// C++ code for the deleting a node from end
// in two traversal
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
Node(int value)
{
this->data = value;
this->next = NULL;
}
};
int length(Node* head)
{
Node* temp = head;
int count = 0;
while (temp != NULL) {
count++;
temp = temp->next;
}
return count;
}
void printList(Node* head)
{
Node* ptr = head;
while (ptr != NULL) {
cout << ptr->data << " ";
ptr = ptr->next;
}
cout << endl;
}
Node* deleteNthNodeFromEnd(Node* head, int n)
{
int Length = length(head);
int nodeFromBeginning = Length - n + 1;
Node* prev = NULL;
Node* temp = head;
for (int i = 1; i < nodeFromBeginning; i++) {
prev = temp;
temp = temp->next;
}
if (prev == NULL) {
head = head->next;
return head;
}
else {
prev->next = prev->next->next;
return head;
}
}
int main()
{
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(4);
head->next->next->next->next = new Node(5);
cout<<"Linked List before Deletion:"<<endl;
printList(head);
head = deleteNthNodeFromEnd(head, 4);
cout<<"Linked List after Deletion: "<<endl;
printList(head);
return 0;
}
Java
class Node {
int data;
Node next;
Node(int value)
{
this.data = value;
this.next = null;
}
}
class Main {
static int length(Node head)
{
Node temp = head;
int count = 0;
while (temp != null) {
count++;
temp = temp.next;
}
return count;
}
static void printList(Node head)
{
Node ptr = head;
while (ptr != null) {
System.out.print(ptr.data + " ");
ptr = ptr.next;
}
System.out.println();
}
static Node deleteNthNodeFromEnd(Node head, int n)
{
int Length = length(head);
int nodeFromBeginning = Length - n + 1;
Node prev = null;
Node temp = head;
for (int i = 1; i < nodeFromBeginning; i++) {
prev = temp;
temp = temp.next;
}
if (prev == null) {
head = head.next;
return head;
}
else {
prev.next = prev.next.next;
return head;
}
}
public static void main(String[] args)
{
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
System.out.println("Linked List before Deletion:");
printList(head);
head = deleteNthNodeFromEnd(head, 4);
System.out.println("Linked List after Deletion:");
printList(head);
}
}
Python
# Python code for the deleting a node from end
# in two traversal
class Node:
def __init__(self, value):
self.data = value
self.next = None
def length(head):
temp = head
count = 0
while(temp != None):
count += 1
temp = temp.next
return count
def printList(head):
ptr = head
while(ptr != None):
print (ptr.data, end =" ")
ptr = ptr.next
print()
def deleteNthNodeFromEnd(head, n):
Length = length(head)
nodeFromBeginning = Length - n + 1
prev = None
temp = head
for i in range(1, nodeFromBeginning):
prev = temp
temp = temp.next
if(prev == None):
head = head.next
return head
else:
prev.next = prev.next.next
return head
if __name__ == '__main__':
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
print("Linked List before Deletion:")
printList(head)
head = deleteNthNodeFromEnd(head, 4)
print("Linked List after Deletion:")
printList(head)
C#
// This C# code defines a class Node which represents a node
// in a linked list. Each node has an integer value 'data'
// and a reference to the next node in the list 'next'. The
// class also defines a static method 'Length' that takes
// the head of a linked list as input and returns the number
// of nodes in the list. Another static method 'PrintList'
// is defined to print the elements of a linked list.
using System;
public class Node {
public int data; // data stored in the node
public Node next; // reference to the next node
// constructor to create a new node with the given data
public Node(int value)
{
this.data = value;
this.next = null;
}
}
public class Program {
// static method to find the length of a linked list
// given its head node
public static int Length(Node head)
{
Node temp = head;
int count = 0;
while (temp != null) // loop until the end of the
// list is reached
{
count++; // increment count for each node
// visited
temp = temp.next; // move to the next node
}
return count;
}
// static method to print the elements of a linked list
public static void PrintList(Node head)
{
Node ptr = head;
while (ptr != null) // loop until the end of the
// list is reached
{
Console.Write(ptr.data
+ " "); // print the data of the
// current node
ptr = ptr.next; // move to the next node
}
Console.WriteLine(); // move to the next line after
// printing the list
}
// static method to delete the nth node from the end of
// a linked list
public static Node DeleteNthNodeFromEnd(Node head,
int n)
{
int Length = Program.Length(
head); // find the length of the list
int nodeFromBeginning
= Length - n
+ 1; // find the index of the node to be
// deleted from the beginning
Node prev = null;
Node temp = head;
for (int i = 1; i < nodeFromBeginning;
i++) // loop until the node before the one to
// be deleted is reached
{
prev = temp;
temp = temp.next;
}
if (prev
== null) // if the first node is to be deleted
{
head = head.next; // update the head node to the
// next node
return head; // return the updated head node
}
else // if any other node is to be deleted
{
prev.next
= prev.next
.next; // skip the node to be deleted
// by updating the reference of
// the previous node
return head; // return the head node
}
}
public static void Main()
{
// create a linked list with 5 nodes
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
// print the linked list before deletion
Console.WriteLine("Linked List before Deletion:");
Program.PrintList(head);
// delete the 4th node from the end of the linked
// list
head = Program.DeleteNthNodeFromEnd(head, 4);
// print the linked list after deletion
Console.WriteLine("Linked List after Deletion:");
Program.PrintList(head);
}
}
Javascript
class Node {
constructor(value) {
this.data = value;
this.next = null;
}
}
function length(head) {
let temp = head;
let count = 0;
while (temp != null) {
count++;
temp = temp.next;
}
return count;
}
function printList(head) {
let ptr = head;
while (ptr != null) {
process.stdout.write(ptr.data + " ");
ptr = ptr.next;
}
console.log();
}
function deleteNthNodeFromEnd(head, n) {
let Length = length(head);
let nodeFromBeginning = Length - n + 1;
let prev = null;
let temp = head;
for (let i = 1; i < nodeFromBeginning; i++) {
prev = temp;
temp = temp.next;
}
if (prev == null) {
head = head.next;
return head;
} else {
prev.next = prev.next.next;
return head;
}
}
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
console.log("Linked List before Deletion:");
printList(head);
head = deleteNthNodeFromEnd(head, 4);
console.log("Linked List after Deletion:");
printList(head);
输出
Linked List before Deletion:
1 2 3 4 5
Linked List after Deletion:
1 3 4 5
双指针方法:
- 取两个指针;第一个将指向链表的头,第二个将指向从头开始的第 N 个节点。
- 现在继续将两个指针同时加一,直到第二个指针指向链表的最后一个节点。
- 经过上一步的操作,现在第一个指针应该指向倒数第N个节点。因此,删除第一个指针指向的节点。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
class LinkedList {
public:
// Linked list Node
class Node {
public:
int data;
Node* next;
Node(int d)
{
data = d;
next = NULL;
}
};
// Head of list
Node* head;
// Function to delete the nth node from the end of the
// given linked list
Node* deleteNode(int key)
{
// We will be using this pointer for holding address
// temporarily while we delete the node
Node* temp;
// First pointer will point to the head of the
// linked list
Node* first = head;
// Second pointer will point to the Nth node from
// the beginning
Node* second = head;
for (int i = 0; i < key; i++) {
// If count of nodes in the given linked list is <= N
if (second->next == NULL) {
// If count = N i.e. delete the head node
if (i == key - 1) {
temp = head;
head = head->next;
free(temp);
}
return head;
}
second = second->next;
}
// Increment both the pointers by one until second
// pointer reaches the end
while (second->next != NULL) {
first = first->next;
second = second->next;
}
// First must be pointing to the Nth node from the
// end by now So, delete the node first is pointing to
temp = first->next;
first->next = first->next->next;
free(temp);
return head;
}
// Function to insert a new Node at front of the list
Node* push(int new_data)
{
Node* new_node = new Node(new_data);
new_node->next = head;
head = new_node;
return head;
}
// Function to print the linked list
void printList()
{
Node* tnode = head;
while (tnode != NULL) {
cout << (tnode->data) << (" ");
tnode = tnode->next;
}
}
};
// Driver code
int main()
{
LinkedList* llist = new LinkedList();
llist->head = llist->push(7);
llist->head = llist->push(1);
llist->head = llist->push(3);
llist->head = llist->push(2);
cout << ("Created Linked list is:\n");
llist->printList();
int N = 1;
llist->head = llist->deleteNode(N);
cout << ("\nLinked List after Deletion is:\n");
llist->printList();
}
C
/* C program to merge two sorted linked lists */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
/* Link list node */
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* deleteNode(Node* head, int key)
{
// We will be using this pointer for holding address
// temporarily while we delete the node
Node* temp;
// First pointer will point to the head of the linked
// list
Node* first = head;
// Second pointer will point to the Nth node from the
// beginning
Node* second = head;
for (int i = 0; i < key; i++) {
// If count of nodes in the given linked list is <=N
if (second->next == NULL) {
// If count = N i.e. delete the head node
if (i == key - 1) {
temp = head;
head = head->next;
free(temp);
}
return head;
}
second = second->next;
}
// Increment both the pointers by one until
// second pointer reaches the end
while (second->next != NULL) {
first = first->next;
second = second->next;
}
// First must be pointing to the Nth node from the end
// by now So, delete the node first is pointing to
temp = first->next;
first->next = first->next->next;
free(temp);
return head;
}
/* Function to insert a node at the beginning of the
linked list */
void push(Node** head_ref, int new_data)
{
/* allocate node */
Node* new_node = (Node*)malloc(sizeof(Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
// Driver program
int main()
{
struct Node* head = NULL;
push(&head, 7);
push(&head, 1);
push(&head, 3);
push(&head, 2);
printf("Created Linked list is:\n");
printList(head);
int n = 1;
deleteNode(head, n);
printf("\nLinked List after Deletion is:\n");
printList(head);
return 0;
}
Java
// Java implementation of the approach
class LinkedList {
// Head of list
Node head;
// Linked list Node
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
// Function to delete the nth node from
// the end of the given linked list
void deleteNode(int key)
{
// First pointer will point to
// the head of the linked list
Node first = head;
// Second pointer will point to the
// Nth node from the beginning
Node second = head;
for (int i = 0; i < key; i++) {
// If count of nodes in the given
// linked list is <= N
if (second.next == null) {
// If count = N i.e. delete the head node
if (i == key - 1)
head = head.next;
return;
}
second = second.next;
}
// Increment both the pointers by one until
// second pointer reaches the end
while (second.next != null) {
first = first.next;
second = second.next;
}
// First must be pointing to the
// Nth node from the end by now
// So, delete the node first is pointing to
first.next = first.next.next;
}
// Function to insert a new Node at front of the list
public void push(int new_data)
{
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
// Function to print the linked list
public void printList()
{
Node tnode = head;
while (tnode != null) {
System.out.print(tnode.data + " ");
tnode = tnode.next;
}
}
// Driver code
public static void main(String[] args)
{
LinkedList llist = new LinkedList();
llist.push(7);
llist.push(1);
llist.push(3);
llist.push(2);
System.out.println("\nCreated Linked list is:");
llist.printList();
int N = 1;
llist.deleteNode(N);
System.out.println("\nLinked List after Deletion is:");
llist.printList();
}
}
Python
# Python3 implementation of the approach
class Node:
def __init__(self, new_data):
self.data = new_data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
# createNode and make linked list
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
def deleteNode(self, n):
first = self.head
second = self.head
for i in range(n):
# If count of nodes in the
# given list is less than 'n'
if(second.next == None):
# If index = n then
# delete the head node
if(i == n - 1):
self.head = self.head.next
return self.head
second = second.next
while(second.next != None):
second = second.next
first = first.next
first.next = first.next.next
def printList(self):
tmp_head = self.head
while(tmp_head != None):
print(tmp_head.data, end = ' ')
tmp_head = tmp_head.next
# Driver Code
llist = LinkedList()
llist.push(7)
llist.push(1)
llist.push(3)
llist.push(2)
print("Created Linked list is:")
llist.printList()
llist.deleteNode(1)
print("\nLinked List after Deletion is:")
llist.printList()
C#
// C# implementation of the approach
using System;
public class LinkedList
{
// Head of list
public Node head;
// Linked list Node
public class Node
{
public int data;
public Node next;
public Node(int d)
{
data = d;
next = null;
}
}
// Function to delete the nth node from
// the end of the given linked list
void deleteNode(int key)
{
// First pointer will point to
// the head of the linked list
Node first = head;
// Second pointer will point to the
// Nth node from the beginning
Node second = head;
for (int i = 0; i < key; i++)
{
// If count of nodes in the given
// linked list is <= N
if (second.next == null)
{
// If count = N i.e. delete the head node
if (i == key - 1)
head = head.next;
return;
}
second = second.next;
}
// Increment both the pointers by one until
// second pointer reaches the end
while (second.next != null)
{
first = first.next;
second = second.next;
}
// First must be pointing to the
// Nth node from the end by now
// So, delete the node first is pointing to
first.next = first.next.next;
}
// Function to insert a new Node at front of the list
public void push(int new_data)
{
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
// Function to print the linked list
public void printList()
{
Node tnode = head;
while (tnode != null)
{
Console.Write(tnode.data + " ");
tnode = tnode.next;
}
}
// Driver code
public static void Main(String[] args)
{
LinkedList llist = new LinkedList();
llist.push(7);
llist.push(1);
llist.push(3);
llist.push(2);
Console.WriteLine("\nCreated Linked list is:");
llist.printList();
int N = 1;
llist.deleteNode(N);
Console.WriteLine("\nLinked List after Deletion is:");
llist.printList();
}
}
Javascript
<script>
// javascript implementation of the approach
// Head of list
var head;
// Linked list Node
class Node {
constructor(val) {
this.data = val;
this.next = null;
}
}
// Function to delete the nth node from
// the end of the given linked list
function deleteNode(key) {
// First pointer will point to
// the head of the linked list
var first = head;
// Second pointer will point to the
// Nth node from the beginning
var second = head;
for (i = 0; i < key; i++) {
// If count of nodes in the given
// linked list is <= N
if (second.next == null) {
// If count = N i.e. delete the head node
if (i == key - 1)
head = head.next;
return;
}
second = second.next;
}
// Increment both the pointers by one until
// second pointer reaches the end
while (second.next != null) {
first = first.next;
second = second.next;
}
// First must be pointing to the
// Nth node from the end by now
// So, delete the node first is pointing to
first.next = first.next.next;
}
// Function to insert a new Node at front of the list
function push(new_data) {
var new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
// Function to print the linked list
function printList() {
var tnode = head;
while (tnode != null) {
document.write(tnode.data + " ");
tnode = tnode.next;
}
}
// Driver code
push(7);
push(1);
push(3);
push(2);
document.write("\nCreated Linked list is:<br/>");
printList();
var N = 1;
deleteNode(N);
document.write("<br/>Linked List after Deletion is:<br/>");
printList();
</script>
输出
Created Linked list is:
2 3 1 7
Linked List after Deletion is:
2 3 1
时间复杂度:O(N),其中 N 是给定链表中的节点数。 辅助空间:O(1)