Dada una lista enlazada de segmentos de línea, elimine los puntos medios

Dada una lista enlazada de coordenadas donde los puntos adyacentes forman una línea vertical o una línea horizontal. Elimine puntos de la lista vinculada que se encuentran en medio de una línea horizontal o vertical.

Ejemplos: 

Input:  (0,10)->(1,10)->(5,10)->(7,10)
                                  |
                                (7,5)->(20,5)->(40,5)
Output: Linked List should be changed to following
        (0,10)->(7,10)
                  |
                (7,5)->(40,5) 
The given linked list represents a horizontal line from (0,10) 
to (7, 10) followed by a vertical line from (7, 10) to (7, 5), 
followed by a horizontal line from (7, 5) to (40, 5).

Input:     (2,3)->(4,3)->(6,3)->(10,3)->(12,3)
Output: Linked List should be changed to following
    (2,3)->(12,3) 
There is only one vertical line, so all middle points are removed.

Fuente: experiencia de entrevista de Microsoft

La idea es realizar un seguimiento del Node actual, el siguiente Node y el siguiente-siguiente Node. Si bien el siguiente Node es el mismo que el siguiente, siga eliminando el siguiente Node. En este procedimiento completo, debemos vigilar el cambio de punteros y verificar los valores NULL.

Las siguientes son implementaciones de la idea anterior. 

C++

// C++ program to remove intermediate points
// in a linked list that represents horizontal
// and vertical line segments
#include <bits/stdc++.h>
using namespace std;
 
// Node has 3 fields including x, y
// coordinates and a pointer
// to next node
class Node
{
    public:
    int x, y;
    Node *next;
};
 
/* Function to insert a node at the beginning */
void push(Node ** head_ref, int x,int y)
{
    Node* new_node =new Node();
    new_node->x = x;
    new_node->y = y;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}
 
/* Utility function to print a singly linked list */
void printList(Node *head)
{
    Node *temp = head;
    while (temp != NULL)
    {
        cout << "(" << temp->x << "," << temp->y << ")-> ";
        temp = temp->next;
    }
    cout<<endl;
 
}
 
// Utility function to remove Next from linked list
// and link nodes after it to head
void deleteNode(Node *head, Node *Next)
{
    head->next = Next->next;
    Next->next = NULL;
    free(Next);
}
 
// This function deletes middle nodes in a sequence of
// horizontal and vertical line segments represented by
// linked list.
Node* deleteMiddle(Node *head)
{
    // If only one node or no node...Return back
    if (head == NULL || head->next == NULL ||
                    head->next->next == NULL)
        return head;
 
    Node* Next = head->next;
    Node *NextNext = Next->next ;
 
    // Check if this is a vertical line or horizontal line
    if (head->x == Next->x)
    {
        // Find middle nodes with same x value, and delete them
        while (NextNext != NULL && Next->x == NextNext->x)
        {
            deleteNode(head, Next);
 
            // Update Next and NextNext for next iteration
            Next = NextNext;
            NextNext = NextNext->next;
        }
    }
    else if (head->y==Next->y) // If horizontal line
    {
        // Find middle nodes with same y value, and delete them
        while (NextNext != NULL && Next->y == NextNext->y)
        {
            deleteNode(head, Next);
 
            // Update Next and NextNext for next iteration
            Next = NextNext;
            NextNext = NextNext->next;
        }
    }
    else // Adjacent points must have either same x or same y
    {
        puts("Given linked list is not valid");
        return NULL;
    }
 
    // Recur for next segment
    deleteMiddle(head->next);
 
    return head;
}
 
// Driver program to test above functions
int main()
{
    Node *head = NULL;
 
    push(&head, 40,5);
    push(&head, 20,5);
    push(&head, 10,5);
    push(&head, 10,8);
    push(&head, 10,10);
    push(&head, 3,10);
    push(&head, 1,10);
    push(&head, 0,10);
    cout << "Given Linked List: \n";
    printList(head);
 
    if (deleteMiddle(head) != NULL);
    {
        cout << "Modified Linked List: \n";
        printList(head);
    }
    return 0;
}
// This is code is contributed by rathbhupendra

C

// C program to remove intermediate points in a linked list
// that represents horizontal and vertical line segments
#include <stdio.h>
#include <stdlib.h>
 
// Node has 3 fields including x, y coordinates and a pointer
// to next node
struct Node
{
    int x, y;
    struct Node *next;
};
 
/* Function to insert a node at the beginning */
void push(struct Node ** head_ref, int x,int y)
{
    struct Node* new_node =
           (struct Node*) malloc(sizeof(struct Node));
    new_node->x  = x;
    new_node->y  = y;
    new_node->next = (*head_ref);
    (*head_ref)  = new_node;
}
 
/* Utility function to print a singly linked list */
void printList(struct Node *head)
{
    struct Node *temp = head;
    while (temp != NULL)
    {
        printf("(%d,%d)-> ", temp->x,temp->y);
        temp = temp->next;
    }
    printf("\n");
 
}
 
// Utility function to remove Next from linked list
// and link nodes after it to head
void deleteNode(struct Node *head, struct Node *Next)
{
    head->next = Next->next;
    Next->next = NULL;
    free(Next);
}
 
// This function deletes middle nodes in a sequence of
// horizontal and vertical line segments represented by
// linked list.
struct Node* deleteMiddle(struct Node *head)
{
    // If only one node or no node...Return back
    if (head==NULL || head->next ==NULL || head->next->next==NULL)
        return head;
 
    struct Node* Next = head->next;
    struct Node *NextNext = Next->next ;
 
    // Check if this is a vertical line or horizontal line
    if (head->x == Next->x)
    {
        // Find middle nodes with same x value, and delete them
        while (NextNext !=NULL && Next->x==NextNext->x)
        {
            deleteNode(head, Next);
 
            // Update Next and NextNext for next iteration
            Next = NextNext;
            NextNext = NextNext->next;
        }
    }
    else if (head->y==Next->y) // If horizontal line
    {
        // Find middle nodes with same y value, and delete them
        while (NextNext !=NULL && Next->y==NextNext->y)
        {
            deleteNode(head, Next);
 
            // Update Next and NextNext for next iteration
            Next = NextNext;
            NextNext = NextNext->next;
        }
    }
    else  // Adjacent points must have either same x or same y
    {
        puts("Given linked list is not valid");
        return NULL;
    }
 
    // Recur for next segment
    deleteMiddle(head->next);
 
    return head;
}
 
// Driver program to test above functions
int main()
{
    struct Node *head = NULL;
 
    push(&head, 40,5);
    push(&head, 20,5);
    push(&head, 10,5);
    push(&head, 10,8);
    push(&head, 10,10);
    push(&head, 3,10);
    push(&head, 1,10);
    push(&head, 0,10);
    printf("Given Linked List: \n");
    printList(head);
 
    if (deleteMiddle(head) != NULL);
    {
        printf("Modified Linked List: \n");
        printList(head);
    }
    return 0;
}

Java

// Java program to remove middle points in a linked list of
// line segments,
class LinkedList
{
    Node head;  // head of list
 
    /* Linked list Node*/
    class Node
    {
        int x,y;
        Node next;
        Node(int x, int y)
        {
            this.x = x;
            this.y = y;
            next = null;
        }
    }
 
    // This function deletes middle nodes in a sequence of
    // horizontal and vertical line segments represented
    // by linked list.
    Node deleteMiddle()
    {
        // If only one node or no node...Return back
        if (head == null || head.next == null ||
            head.next.next == null)
            return head;
 
        Node Next = head.next;
        Node NextNext = Next.next;
 
        // check if this is vertical or horizontal line
        if (head.x == Next.x)
        {
            // Find middle nodes with same value as x and
            // delete them.
            while (NextNext != null && Next.x == NextNext.x)
            {
                head.next = Next.next;
                Next.next = null;
 
                // Update NextNext for the next iteration
                Next = NextNext;
                NextNext = NextNext.next;
            }
        }
 
        // if horizontal
        else if (head.y == Next.y)
        {
            // find middle nodes with same value as y and
            // delete them
            while (NextNext != null && Next.y == NextNext.y)
            {
                head.next = Next.next;
                Next.next = null;
 
                // Update NextNext for the next iteration
                Next = NextNext;
                NextNext = NextNext.next;
            }
        }
 
        // Adjacent points should have same x or same y
        else
        {
            System.out.println("Given list is not valid");
            return null;
        }
 
        // recur for other segment
 
        // temporarily store the head and move head forward.
        Node temp = head;
        head = head.next;
 
        // call deleteMiddle() for next segment
        this.deleteMiddle();
 
        // restore head
        head = temp;
 
        // return the head
        return head;
    }
 
    /*  Given a reference (pointer to pointer) to the head
        of a list and an int, push a new node on the front
        of the list. */
    void push(int x, int y)
    {
        /* 1 & 2: Allocate the Node &
                  Put in the data*/
        Node new_node = new Node(x,y);
 
        /* 3. Make next of new Node as head */
        new_node.next = head;
 
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
 
 
    void printList()
    {
        Node temp = head;
        while (temp != null)
        {
            System.out.print("("+temp.x+","+temp.y+")->");
            temp = temp.next;
        }
        System.out.println();
    }
 
 
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        LinkedList llist = new LinkedList();
 
        llist.push(40,5);
        llist.push(20,5);
        llist.push(10,5);
        llist.push(10,8);
        llist.push(10,10);
        llist.push(3,10);
        llist.push(1,10);
        llist.push(0,10);
 
        System.out.println("Given list");
        llist.printList();
 
        if (llist.deleteMiddle() != null)
        {
            System.out.println("Modified Linked List is");
            llist.printList();
        }
    }
} /* This code is contributed by Rajat Mishra */

Python3

# Python program to remove middle points in a linked list of
# line segments,
class LinkedList(object):
    def __init__(self):
        self.head = None
 
    # Linked list Node
    class Node(object):
        def __init__(self, x, y):
            self.x = x
            self.y = y
            self.next = None
 
    # This function deletes middle nodes in a sequence of
    # horizontal and vertical line segments represented
    # by linked list.
    def deleteMiddle(self):
        # If only one node or no node...Return back
        if self.head == None or self.head.next == None or self.head.next.next == None:
            return self.head
        Next = self.head.next
        NextNext = Next.next
        # check if this is vertical or horizontal line
        if self.head.x == Next.x:
            # Find middle nodes with same value as x and
            # delete them.
            while NextNext != None and Next.x == NextNext.x:
                self.head.next = Next.next
                Next.next = None
                # Update NextNext for the next iteration
                Next = NextNext
                NextNext = NextNext.next
        elif self.head.y == Next.y:
            # find middle nodes with same value as y and
            # delete them
            while NextNext != None and Next.y == NextNext.y:
                self.head.next = Next.next
                Next.next = None
                # Update NextNext for the next iteration
                Next = NextNext
                NextNext = NextNext.next
        else:
            # Adjacent points should have same x or same y
            print ("Given list is not valid")
            return None
        # recur for other segment
        # temporarily store the head and move head forward.
        temp = self.head
        self.head = self.head.next
        # call deleteMiddle() for next segment
        self.deleteMiddle()
        # restore head
        self.head = temp
        # return the head
        return self.head
 
    # Given a reference (pointer to pointer) to the head
    # of a list and an int, push a new node on the front
    # of the list.
    def push(self, x, y):
        # 1 & 2: Allocate the Node &
        # Put in the data
        new_node = self.Node(x, y)
        # 3. Make next of new Node as head
        new_node.next = self.head
        # 4. Move the head to point to new Node
        self.head = new_node
 
    def printList(self):
        temp = self.head
        while temp != None:
            print ("(" + str(temp.x) + "," + str(temp.y) + ")->",end=" ")
            temp = temp.next
        print ()
 
# Driver program
llist = LinkedList()
llist.push(40,5)
llist.push(20,5)
llist.push(10,5)
llist.push(10,8)
llist.push(10,10)
llist.push(3,10)
llist.push(1,10)
llist.push(0,10)
 
print ("Given list")
llist.printList()
 
if llist.deleteMiddle() != None:
    print ("Modified Linked List is")
    llist.printList()
 
# This code is contributed by BHAVYA JAIN

C#

// C# program to remove middle
// points in a linked list of
// line segments,
using System;
 
public class LinkedList
{
    Node head; // head of list
 
    /* Linked list Node*/
    class Node
    {
        public int x,y;
        public Node next;
        public Node(int x, int y)
        {
            this.x = x;
            this.y = y;
            next = null;
        }
    }
 
    // This function deletes middle
    // nodes in a sequence of horizontal and
    // vertical line segments represented
    // by linked list.
    Node deleteMiddle()
    {
        // If only one node or no node...Return back
        if (head == null || head.next == null ||
            head.next.next == null)
            return head;
 
        Node Next = head.next;
        Node NextNext = Next.next;
 
        // check if this is vertical or horizontal line
        if (head.x == Next.x)
        {
            // Find middle nodes with same
            //  value as x and delete them.
            while (NextNext != null &&
                    Next.x == NextNext.x)
            {
                head.next = Next.next;
                Next.next = null;
 
                // Update NextNext for
                // the next iteration
                Next = NextNext;
                NextNext = NextNext.next;
            }
        }
 
        // if horizontal
        else if (head.y == Next.y)
        {
            // find middle nodes with same
            // value as y and delete them
            while (NextNext != null && Next.y == NextNext.y)
            {
                head.next = Next.next;
                Next.next = null;
 
                // Update NextNext for the next iteration
                Next = NextNext;
                NextNext = NextNext.next;
            }
        }
 
        // Adjacent points should have same x or same y
        else
        {
            Console.WriteLine("Given list is not valid");
            return null;
        }
 
        // recur for other segment
 
        // temporarily store the
        // head and move head forward.
        Node temp = head;
        head = head.next;
 
        // call deleteMiddle() for next segment
        this.deleteMiddle();
 
        // restore head
        head = temp;
 
        // return the head
        return head;
    }
 
    /* Given a reference (pointer to pointer) to the head
        of a list and an int, push a new node on the front
        of the list. */
    void push(int x, int y)
    {
        /* 1 & 2: Allocate the Node &
                Put in the data*/
        Node new_node = new Node(x,y);
 
        /* 3. Make next of new Node as head */
        new_node.next = head;
 
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
 
 
    void printList()
    {
        Node temp = head;
        while (temp != null)
        {
            Console.Write("("+temp.x + "," + temp.y + ")->");
            temp = temp.next;
        }
        Console.WriteLine();
    }
 
 
    /* Driver code */
    public static void Main(String []args)
    {
        LinkedList llist = new LinkedList();
 
        llist.push(40,5);
        llist.push(20,5);
        llist.push(10,5);
        llist.push(10,8);
        llist.push(10,10);
        llist.push(3,10);
        llist.push(1,10);
        llist.push(0,10);
 
        Console.WriteLine("Given list");
        llist.printList();
 
        if (llist.deleteMiddle() != null)
        {
            Console.WriteLine("Modified Linked List is");
            llist.printList();
        }
    }
}
 
// This code is contributed by Rajput-Ji

Javascript

<script>
 
// Javascript program to remove middle
// points in a linked list of
// line segments,
var  head; // head of list
 
    /* Linked list Node */
    class Node {
 
constructor(x , y) {
            this.x = x;
            this.y = y;
            this.next = null;
        }
    }
 
    // This function deletes middle
    // nodes in a sequence of
    // horizontal and vertical line
    // segments represented
    // by linked list.
    function deleteMiddle() {
        // If only one node or no
        // node...Return back
        if (head == null || head.next == null ||
        head.next.next == null)
            return head;
 
var Next = head.next;
var NextNext = Next.next;
 
        // check if this is vertical or
        // horizontal line
        if (head.x == Next.x) {
            // Find middle nodes with same
            // value as x and
            // delete them.
            while (NextNext != null &&
            Next.x == NextNext.x)
            {
                head.next = Next.next;
                Next.next = null;
 
                // Update NextNext for the next iteration
                Next = NextNext;
                NextNext = NextNext.next;
            }
        }
 
        // if horizontal
        else if (head.y == Next.y) {
            // find middle nodes with same value as y and
            // delete them
            while (NextNext != null &&
            Next.y == NextNext.y) {
                head.next = Next.next;
                Next.next = null;
 
                // Update NextNext for the next iteration
                Next = NextNext;
                NextNext = NextNext.next;
            }
        }
 
        // Adjacent points should have same x or same y
        else {
            document.write("Given list is not valid");
            return null;
        }
 
        // recur for other segment
 
        // temporarily store the head and move head forward.
var temp = head;
        head = head.next;
 
        // call deleteMiddle() for next segment
        this.deleteMiddle();
 
        // restore head
        head = temp;
 
        // return the head
        return head;
    }
 
    /*
     Given a reference (pointer to pointer) to
     the head of a list and an int, push
     a new node on the front of the list.
     */
    function push(x , y) {
        /*
         1 & 2: Allocate the Node & Put in the data
         */
var new_node = new Node(x, y);
 
        /* 3. Make next of new Node as head */
        new_node.next = head;
 
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
 
    function printList() {
var temp = head;
        while (temp != null) {
            document.write("(" + temp.x + "," +
            temp.y + ")->");
            temp = temp.next;
        }
        document.write("<br/>");
    }
 
    /* Driver program to test above functions */
     
 
        push(40, 5);
        push(20, 5);
        push(10, 5);
        push(10, 8);
        push(10, 10);
        push(3, 10);
        push(1, 10);
        push(0, 10);
 
        document.write("Given list<br/>");
        printList();
 
        if (deleteMiddle() != null) {
            document.write("Modified Linked List is<br/>");
            printList();
        }
 
// This code contributed by gauravrajput1
 
</script>
Producción

Given Linked List: 
(0,10)-> (1,10)-> (3,10)-> (10,10)-> (10,8)-> (10,5)-> (20,5)-> (40,5)-> 
Modified Linked List: 
(0,10)-> (10,10)-> (10,5)-> (40,5)-> 

La complejidad temporal de la solución anterior es O(n) donde n es un número de Nodes en la lista enlazada dada.

Ejercicio: 

El código anterior es recursivo, escriba un código iterativo para el mismo problema. Consulte a continuación la solución.
Enfoque iterativo para eliminar puntos medios en una lista enlazada de segmentos de línea 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *