先决条件:双向链表
给定一个双向链表,任务是将开头的第K个节点与结尾的第K个节点交换。
注意:请注意这里交换的是节点而不是节点中的数据。
例子:
Input: DLL = 1 <-> 2 <-> 3 <-> 4 <-> 5 <-> 6, K = 3
Output: 1 2 4 3 5 6
Explanation:
Third node from the beginning(3) is swapped with third node from the ending(4).
Input: DLL = 1 <-> 2 <-> 3 <-> 4 <-> 5, K = 1
Output: 5 2 3 4 1
做法:思路是从头开始遍历到第K个元素,从结尾开始遍历到第K个节点,改变前后指针。设K1是从头开始的第K个节点,而K2是从结束开始的第K个节点。然后:
- K2的前一个节点必须更改为K1的前一个节点。
- K2的下一个节点必须更改为K1的下一个节点。
- K1的前一个节点必须更改为K2的前一个节点。
- K1的下一个节点必须更改为K2的下一个节点。
下面是上述方法的实现:
Java
// Java implementation of the approach
public class GFG {
// Doubly Linked List implementation
private class Node {
private int data;
private Node next;
private Node previous;
public Node(int data, Node next,
Node previous)
{
this.data = data;
this.next = next;
this.previous = previous;
}
public int getData()
{
return data;
}
public void setData(int data)
{
this.data = data;
}
public Node getNext()
{
return next;
}
public void setNext(Node next)
{
this.next = next;
}
public Node getPrevious()
{
return previous;
}
public void setPrevious(Node previous)
{
this.previous = previous;
}
}
private Node head;
private Node tail;
public GFG()
{
this.head = null;
this.tail = null;
}
public Node getHead()
{
return head;
}
public void setHead(Node head)
{
this.head = head;
}
public Node getTail()
{
return tail;
}
public void setTail(Node tail)
{
this.tail = tail;
}
// Function to replace Kth node from
// beginning with Kth node from end
public void swapNode(Node headReference,
Node tailReference, int k)
{
// If K is 1, then the first node
// has to be swapped with the
// last node in the doubly linked list
if (k == 1) {
swapFirstAndLast(headReference,
tailReference);
return;
}
// If k is N, then the last node
// has to be swapped with the
// first node in the doubly linked list
int nodeCount = getCount(headReference);
if (k == nodeCount) {
swapFirstAndLast(headReference,
tailReference);
return;
}
// If the Kth node from
// the beginning and Kth node
// from the ending are same
if (2 * k - 1 == nodeCount) {
return;
}
// fNode represents Kth node
// from the beginning
Node fNode = headReference;
for (int i = 1; i < k; i++) {
fNode = fNode.getNext();
}
Node fNodePrevious = fNode.getPrevious();
Node fNodeNext = fNode.getNext();
// sNode represents Kth node
// from the ending
Node sNode = tailReference;
for (int i = 1; i < k; i++) {
sNode = sNode.getPrevious();
}
Node sNodePrevious = sNode.getPrevious();
Node sNodeNext = sNode.getNext();
// Checking if any of the pointers is null
// and interchanging the pointers
if (fNodePrevious != null && sNode != null) {
fNodePrevious.setNext(sNode);
sNode.setPrevious(fNodePrevious);
sNode.setNext(fNodeNext);
fNodeNext.setPrevious(sNode);
}
if (sNodePrevious != null && sNodeNext != null) {
sNodeNext.setPrevious(fNode);
fNode.setNext(sNodeNext);
sNodePrevious.setNext(fNode);
fNode.setPrevious(sNodePrevious);
}
}
// Function to swap the first and
// last node in the doubly linked list
private void swapFirstAndLast(
Node headReference,
Node tailReference)
{
Node headRef = headReference;
Node tailRef = tailReference;
headReference
= headReference.getNext();
tailReference
= tailReference.getPrevious();
tailReference.setNext(headRef);
headRef.setPrevious(tailReference);
headRef.setNext(null);
this.setTail(tailReference.getNext());
headReference.setPrevious(tailRef);
tailRef.setNext(headReference);
tailRef.setPrevious(null);
this.setHead(headReference
.getPrevious());
}
// Function to return the number of nodes
// in the linked list
private int getCount(Node headReference)
{
int nodeCount = 0;
while (headReference != null) {
nodeCount++;
headReference = headReference
.getNext();
}
return nodeCount;
}
// Function to print the Linked List
public void printList(Node headReference)
{
if (headReference == null) {
System.out.println(
"Doubly linked list is empty");
return;
}
else {
while (headReference != null) {
System.out.print(
headReference.getData()
+ " ");
headReference
= headReference.getNext();
}
}
}
// Function to insert a node at
// the end of the doubly linked list
public void push(int data)
{
Node newNode
= new Node(data, null, null);
if (head == null) {
head = tail = newNode;
}
else {
tail.setNext(newNode);
newNode.setPrevious(tail);
tail = newNode;
}
}
// Driver code
public static void main(String[] args)
{
// Creating an object for the class
GFG list = new GFG();
// Adding data to the linked list
list.push(1);
list.push(2);
list.push(3);
list.push(4);
list.push(5);
// Calling the function
int K = 2;
list.swapNode(list.getHead(),
list.getTail(), K);
list.printList(list.getHead());
}
}
C#
// C# implementation of the approach
using System;
public class GFG {
// Doubly Linked List implementation
private class Node {
private int data;
private Node next;
private Node previous;
public Node(int data, Node next,
Node previous)
{
this.data = data;
this.next = next;
this.previous = previous;
}
public int getData()
{
return data;
}
public void setData(int data)
{
this.data = data;
}
public Node getNext()
{
return next;
}
public void setNext(Node next)
{
this.next = next;
}
public Node getPrevious()
{
return previous;
}
public void setPrevious(Node previous)
{
this.previous = previous;
}
}
private Node head;
private Node tail;
public GFG()
{
this.head = null;
this.tail = null;
}
Node getHead()
{
return head;
}
void setHead(Node head)
{
this.head = head;
}
Node getTail()
{
return tail;
}
void setTail(Node tail)
{
this.tail = tail;
}
// Function to replace Kth node from
// beginning with Kth node from end
void swapNode(Node headReference,
Node tailReference, int k)
{
// If K is 1, then the first node
// has to be swapped with the
// last node in the doubly linked list
if (k == 1) {
swapFirstAndLast(headReference,
tailReference);
return;
}
// If k is N, then the last node
// has to be swapped with the
// first node in the doubly linked list
int nodeCount = getCount(headReference);
if (k == nodeCount) {
swapFirstAndLast(headReference,
tailReference);
return;
}
// If the Kth node from
// the beginning and Kth node
// from the ending are same
if (2 * k - 1 == nodeCount) {
return;
}
// fNode represents Kth node
// from the beginning
Node fNode = headReference;
for (int i = 1; i < k; i++) {
fNode = fNode.getNext();
}
Node fNodePrevious = fNode.getPrevious();
Node fNodeNext = fNode.getNext();
// sNode represents Kth node
// from the ending
Node sNode = tailReference;
for (int i = 1; i < k; i++) {
sNode = sNode.getPrevious();
}
Node sNodePrevious = sNode.getPrevious();
Node sNodeNext = sNode.getNext();
// Checking if any of the pointers is null
// and interchanging the pointers
if (fNodePrevious != null && sNode != null) {
fNodePrevious.setNext(sNode);
sNode.setPrevious(fNodePrevious);
sNode.setNext(fNodeNext);
fNodeNext.setPrevious(sNode);
}
if (sNodePrevious != null && sNodeNext != null) {
sNodeNext.setPrevious(fNode);
fNode.setNext(sNodeNext);
sNodePrevious.setNext(fNode);
fNode.setPrevious(sNodePrevious);
}
}
// Function to swap the first and
// last node in the doubly linked list
private void swapFirstAndLast(
Node headReference,
Node tailReference)
{
Node headRef = headReference;
Node tailRef = tailReference;
headReference
= headReference.getNext();
tailReference
= tailReference.getPrevious();
tailReference.setNext(headRef);
headRef.setPrevious(tailReference);
headRef.setNext(null);
this.setTail(tailReference.getNext());
headReference.setPrevious(tailRef);
tailRef.setNext(headReference);
tailRef.setPrevious(null);
this.setHead(headReference
.getPrevious());
}
// Function to return the number of nodes
// in the linked list
private int getCount(Node headReference)
{
int nodeCount = 0;
while (headReference != null) {
nodeCount++;
headReference = headReference
.getNext();
}
return nodeCount;
}
// Function to print the Linked List
void printList(Node headReference)
{
if (headReference == null) {
Console.WriteLine(
"Doubly linked list is empty");
return;
}
else {
while (headReference != null) {
Console.Write(
headReference.getData()
+ " ");
headReference
= headReference.getNext();
}
}
}
// Function to insert a node at
// the end of the doubly linked list
void Push(int data)
{
Node newNode
= new Node(data, null, null);
if (head == null) {
head = tail = newNode;
}
else {
tail.setNext(newNode);
newNode.setPrevious(tail);
tail = newNode;
}
}
// Driver code
public static void Main(String[] args)
{
// Creating an object for the class
GFG list = new GFG();
// Adding data to the linked list
list.Push(1);
list.Push(2);
list.Push(3);
list.Push(4);
list.Push(5);
// Calling the function
int K = 2;
list.swapNode(list.getHead(),
list.getTail(), K);
list.printList(list.getHead());
}
}
// This code is contributed by 29AjayKumar
Java
//java program to swap Kth node from beginning with
//the Kth node from the end without using temporary
//node and without swapping the data
public class GFG {
//head pointer for pointing to start of the linked list
//last pointer for pointing to last node of the linked list
Node head = null,last = null;
//class Node
class Node{
int data;
Node first,next;
Node(int data){
this.data = data;
first = null;
next = null;
}
}
//function for inserting new node at the
//end of the list using last pointer
void AddLast(int data) {
Node temp = new Node(data);
if(head == null) {
head = temp;
last = temp;
}
else {
last.next = temp;
temp.first = last;
last = temp;
}
}
//function for printing the doubly linked list
void printList() {
Node p = head;
while(p!=null) {
System.out.print(p.data+"<->");
p = p.next;
}
System.out.print("null");
System.out.println();
}
//function for swapping Kth node from
//beginning with Kth node from the end
void swapKthNodes(int k) {
int count = 1;
Node p = head, q = last;
//case 1: to swap the start and end nodes
//case 1 figure
if(k == 1) {
q.first.next = p;
p.first = q.first;
q.next = p.next;
p.next.first = q;
//change these links to null to the break circular link
p.next = null;
q.first = null;
head = q;
last = p;
}
else {
while(p!=null && q!=null && count
输出:
1 4 3 2 5
方法二:不交换元素,不使用临时节点。
方法:有3种情况可以交换节点。
- 交换第一个和最后一个节点(k = 1)
- 交换从头开始的普通第 K 个节点和从末尾开始的第 K 个节点。
- 交换中间节点
情况 1:交换第一个和最后一个节点(k = 1)
脚步:
- 将列表作为循环链表
- 将第一个节点的前一个指针更改为最后一个节点(示例图中为 20)
- 将最后一个节点的下一个指针更改为最后一个节点。在这种情况下,它将是 60。
- 交换后,将头部作为第一个节点。
Consider p and q are the nodes which are to be swapped,
head = q; //change head pointer to point to head node
last = p; //change last pointer to point to last node
情况2:交换从头开始的普通第K个节点和从结束开始的第K个节点。
脚步:
- 让我们考虑 K = 2。所以要交换或互换的节点是 20 和 50,如图所示。
- 使要交换的节点的 first 和 next 指针都指向前一个节点。为此,我们需要将先前节点的链接更改为指向要交换的节点之后的节点。
Consider the nodes to be swapped are p and q:
//Change the link of the next pointer of the previous node to point to
//the next node of to be swapped node.
q.first.next = q.next;
p.first.next = p.next; // Same procedure for the other node
//Make sure to change the previous/first pointer of the next node to
//point to the previous of to be swapped node.
q.next.first = q.first;
p.next.first = p.first;
//Both the first and next pointers points to the previous node as shown in the below figure.
q.next = q.first;
p.next = p.first;
3.交换一个待交换节点与另一个待交换节点的指针。 (第3步表示互换后的图)。
4. 对链接进行必要的更改以使其成为完整列表。
案例3:交换中间节点
脚步:
- 这种情况与情况2相同,唯一的变化是,要交换的节点是中间节点。所以他们两个都在一起(并排)。
- 考虑 p 是要交换的第一个节点,q 是要交换的第二个节点。
- 将 p 上一个节点的 next 指针指向 q 的下一个节点。这一步是为了省略 p 和 q 节点。
- 同理,将q的下一个节点的第一个指针指向q的上一个节点。
- 更改 p 和 q 的链接,使两个节点都指向 p 的前一个节点(下图中的 step2)。
- 相应地建立 p 和 q 的链接,使节点交换位置。
执行:
Java
//java program to swap Kth node from beginning with
//the Kth node from the end without using temporary
//node and without swapping the data
public class GFG {
//head pointer for pointing to start of the linked list
//last pointer for pointing to last node of the linked list
Node head = null,last = null;
//class Node
class Node{
int data;
Node first,next;
Node(int data){
this.data = data;
first = null;
next = null;
}
}
//function for inserting new node at the
//end of the list using last pointer
void AddLast(int data) {
Node temp = new Node(data);
if(head == null) {
head = temp;
last = temp;
}
else {
last.next = temp;
temp.first = last;
last = temp;
}
}
//function for printing the doubly linked list
void printList() {
Node p = head;
while(p!=null) {
System.out.print(p.data+"<->");
p = p.next;
}
System.out.print("null");
System.out.println();
}
//function for swapping Kth node from
//beginning with Kth node from the end
void swapKthNodes(int k) {
int count = 1;
Node p = head, q = last;
//case 1: to swap the start and end nodes
//case 1 figure
if(k == 1) {
q.first.next = p;
p.first = q.first;
q.next = p.next;
p.next.first = q;
//change these links to null to the break circular link
p.next = null;
q.first = null;
head = q;
last = p;
}
else {
while(p!=null && q!=null && count
输出
Before swapping:
10<->20<->30<->40<->50<->60<->null
After swapping nodes for k = 1:
60<->20<->30<->40<->50<->10<->null
After swapping nodes for k = 2:
60<->50<->30<->40<->20<->10<->null
After swapping nodes for k = 3 (middle):
60<->50<->40<->30<->20<->10<->null
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live