Design a data structure that initially contains no elements and supports the following operations:
- insert(x): Inserts the integer x at the end of the data structure.
- print(): Prints all elements of the data structure in their current order(space separated).
- replace(x, sequence): Finds the first occurrence of x and replaces it with all elements of sequence in the same order.
The data structure should maintain the relative order of all elements that are not replaced.
There will be a sequence of q queries, represented by queries[][]. Each query is represented in numeric form:
- [1, x]: Call insert(x).
- [2]: Call print().
- [3, x, a1, a2, ..., am]: Call replace(x, [a1, a2, ..., am]), where m is the size of the sequence.
It is guaranteed that every replace query contains at least one occurrence of x in the data structure.
Note:Â The driver code will process the queries, call the corresponding functions, and print the output of every print() operation followed by a newline.
Examples:
Input: q = 6, queries[][] = [[1, 3], [1, 10], [2], [1, 3], [3, 3, 1, 2, 3], [2]]
Output:
3 10
1 2 3 10 3
Explanation:
insert(3) -> [3]
insert(10) -> [3, 10]
print() -> 3 10
insert(3) -> [3, 10, 3]
replace(3, [1,2,3]) replaces the first 3: [1, 2, 3, 10, 3]
print() -> 1 2 3 10 3Input: q = 6, queries[][] = [[1, 5], [1, 2], [1, 5], [3, 5, 7, 8], [2], [1, 9]]
Output: 7 8 2 5
Explanation:
insert(5) -> [5]
insert(2) -> [5, 2]
insert(5) -> [5, 2, 5]
replace(5, [7, 8]) replaces the first 5 -> [7, 8, 2, 5]
print() -> 7 8 2 5
insert(9) -> [7, 8, 2, 5, 9]
Table of Content
Using Vector
The idea is to store all elements in a vector and find the first occurrence of x. Remove it and insert the given sequence at the same position.
Working of Approach:
- Store all elements in a vector.
- Use push_back() to insert an element at the end.
- Traverse the vector to find the first occurrence of x.
- Erase x and insert the replacement sequence at the same position.
- Traverse the vector to print all elements.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> l;
// Inserts an integer at the end.
void insert(int x) {
l.push_back(x);
}
// Prints the elements of the data structure.
void print() {
for (int x : l)
cout << x << " ";
}
// Replaces the first occurrence of x with the given sequence.
void replace(int x, vector<int>& sequence) {
// Find the first occurrence of x.
auto it = find(l.begin(), l.end(), x);
if (it != l.end()) {
// Remove the first occurrence of x.
it = l.erase(it);
// Insert the sequence at the same position.
l.insert(it, sequence.begin(), sequence.end());
}
}
int main() {
insert(3);
insert(10);
print();
cout << endl;
insert(3);
vector<int> sequence = {1, 2, 3};
replace(3, sequence);
print();
cout << endl;
return 0;
}
import java.util.ArrayList;
class GFG {
// The elements are stored in a dynamic array, in their current order.
private ArrayList<Integer> l;
// The data structure is empty at the start.
public GFG() {
l = new ArrayList<>();
}
// Inserts an integer at the end.
void insert(int x) {
l.add(x);
}
// Prints the elements of the data structure.
void print() {
for (int x : l)
System.out.print(x + " ");
}
// Replaces the first occurrence of x with the given sequence.
void replace(int x, int[] sequence) {
// Find the first occurrence of x.
int pos = l.indexOf(x);
if (pos != -1) {
// Remove the first occurrence of x.
l.remove(pos);
// Insert the sequence at the same position.
ArrayList<Integer> seq = new ArrayList<>();
for (int v : sequence)
seq.add(v);
l.addAll(pos, seq);
}
}
public static void main(String[] args) {
GFG ds = new GFG();
ds.insert(3);
ds.insert(10);
ds.print();
System.out.println();
ds.insert(3);
int[] sequence = {1, 2, 3};
ds.replace(3, sequence);
ds.print();
System.out.println();
}
}
l = []
# Inserts an integer at the end.
def insert(x):
l.append(x)
# Prints the elements of the data structure.
def print_data():
for x in l:
print(x, end=" ")
# Replaces the first occurrence of x with the given sequence.
def replace(x, sequence):
# Find the first occurrence of x.
if x in l:
# Find the position of the first occurrence.
pos = l.index(x)
# Remove the first occurrence of x.
l.pop(pos)
# Insert the sequence at the same position.
l[pos:pos] = sequence
if __name__ == "__main__":
insert(3)
insert(10)
print_data()
print()
insert(3)
sequence = [1, 2, 3]
replace(3, sequence)
print_data()
print()
using System;
using System.Collections.Generic;
class GFG {
static List<int> l = new List<int>();
// Inserts an integer at the end.
static void insert(int x) {
l.Add(x);
}
// Prints the elements of the data structure.
static void print() {
foreach (int x in l)
Console.Write(x + " ");
}
// Replaces the first occurrence of x with the given sequence.
static void replace(int x, int[] sequence) {
// Find the first occurrence of x.
int pos = l.IndexOf(x);
if (pos != -1) {
// Remove the first occurrence of x.
l.RemoveAt(pos);
// Insert the sequence at the same position.
l.InsertRange(pos, sequence);
}
}
static void Main() {
insert(3);
insert(10);
print();
Console.WriteLine();
insert(3);
int[] sequence = {1, 2, 3};
replace(3, sequence);
print();
Console.WriteLine();
}
}
const l = [];
// Inserts an integer at the end.
function insert(x) {
l.push(x);
}
// Prints the elements of the data structure.
function print() {
for (const x of l)
process.stdout.write(x + " ");
}
// Replaces the first occurrence of x with the given sequence.
function replace(x, sequence) {
// Find the first occurrence of x.
const pos = l.indexOf(x);
if (pos !== -1) {
// Remove the first occurrence of x.
l.splice(pos, 1);
// Insert the sequence at the same position.
l.splice(pos, 0, ...sequence);
}
}
// Driver Code
insert(3);
insert(10);
print();
console.log();
insert(3);
const sequence = [1, 2, 3];
replace(3, sequence);
print();
console.log();
Output
3 10 1 2 3 10 3
Time Complexity: insert() - O(1) amortized, print() - O(n), replace() - O(n + m)
Space Complexity: O(n + m), where n is the number of elements in the data structure and m is the size of the sequence.
Using Doubly Linked List
The idea is to store the elements in a doubly linked list, find the first occurrence of x, and replace it with the given sequence at the same position.
Working of Approach:
- Store all elements in a doubly linked list.
- Insert every new element at the end using push_back().
- Find the first occurrence of x using find().
- Erase x and insert the replacement sequence at the same position.
- Traverse the list to print all elements.
Let us understand with an example:
Input: q = 6, queries[][] = [[1, 3], [1, 10], [2], [1, 3], [3, 3, 1, 2, 3], [2]]
- insert(3) -> l = [3]
- insert(10) -> l = [3, 10]
- [2] calls print() -> Output: 3 10
- insert(3) -> l = [3, 10, 3]
- replace(3, [1, 2, 3]) replaces the first 3 -> l = [1, 2, 3, 10, 3]
- [2] calls print() -> Output: 1 2 3 10 3
Hence, the final output is:
3 10
1 2 3 10 3
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
// The elements are stored in a linked list, in their current order.
list<int> l;
// Inserts an integer at the end.
void insert(int x) {
l.push_back(x);
}
// Prints the elements of the data structure.
void print() {
for (int x : l)
cout << x << " ";
}
// Replaces the first occurrence of x with the given sequence.
void replace(int x, vector<int>& sequence) {
// Find the first occurrence of x.
auto it = find(l.begin(), l.end(), x);
if (it != l.end()) {
// Remove the first occurrence of x.
it = l.erase(it);
// Insert the sequence at the same position.
l.insert(it, sequence.begin(), sequence.end());
}
}
int main() {
insert(3);
insert(10);
print();
cout << endl;
insert(3);
vector<int> sequence = {1, 2, 3};
replace(3, sequence);
print();
cout << endl;
return 0;
}
import java.util.LinkedList;
import java.util.ListIterator;
class GFG {
// The elements are stored in a linked list, in their current order.
private LinkedList<Integer> l;
// The data structure is empty at the start.
public GFG() {
l = new LinkedList<>();
}
// Inserts an integer at the end.
void insert(int x) {
l.add(x);
}
// Prints the elements of the data structure.
void print() {
for (int x : l)
System.out.print(x + " ");
}
// Replaces the first occurrence of x with the given sequence.
void replace(int x, int[] sequence) {
// Find the first occurrence of x.
ListIterator<Integer> it = l.listIterator();
while (it.hasNext()) {
if (it.next() == x) {
// Remove the first occurrence of x.
it.remove();
// Insert the sequence at the same position.
for (int v : sequence)
it.add(v);
return;
}
}
}
public static void main(String[] args) {
GFG ds = new GFG();
ds.insert(3);
ds.insert(10);
ds.print();
System.out.println();
ds.insert(3);
int[] sequence = {1, 2, 3};
ds.replace(3, sequence);
ds.print();
System.out.println();
}
}
# The elements are stored in a linked list, in their current order.
# The dummy node sits before the first element, and tail is the last node.
dummy = {'val': 0, 'next': None}
tail = dummy
# Inserts an integer at the end.
def insert(x):
global tail
node = {'val': x, 'next': None}
tail['next'] = node
tail = node
# Prints the elements of the data structure.
def print_data():
cur = dummy['next']
while cur is not None:
print(cur['val'], end=" ")
cur = cur['next']
# Replaces the first occurrence of x with the given sequence.
def replace(x, sequence):
global tail
# Find the node just before the first occurrence of x.
prev = dummy
while prev['next'] is not None and prev['next']['val'] != x:
prev = prev['next']
target = prev['next']
if target is None:
return
# Remove the first occurrence of x, and insert the sequence at the same position.
after = target['next']
cur = prev
for val in sequence:
cur['next'] = {'val': val, 'next': None}
cur = cur['next']
cur['next'] = after
# If the removed node was the last one, the tail moves to the last node of the sequence.
if after is None:
tail = cur
if __name__ == "__main__":
insert(3)
insert(10)
print_data()
print()
insert(3)
sequence = [1, 2, 3]
replace(3, sequence)
print_data()
print()
using System;
using System.Collections.Generic;
class GFG {
// The elements are stored in a linked list, in their current order.
static LinkedList<int> l = new LinkedList<int>();
// Inserts an integer at the end.
static void insert(int x) {
l.AddLast(x);
}
// Prints the elements of the data structure.
static void print() {
foreach (int x in l)
Console.Write(x + " ");
}
// Replaces the first occurrence of x with the given sequence.
static void replace(int x, int[] sequence) {
// Find the first occurrence of x.
LinkedListNode<int> node = l.First;
while (node != null && node.Value != x)
node = node.Next;
if (node != null) {
// Insert the sequence before it, in the same order.
foreach (int v in sequence)
l.AddBefore(node, v);
// Remove the first occurrence of x.
l.Remove(node);
}
}
static void Main() {
insert(3);
insert(10);
print();
Console.WriteLine();
insert(3);
int[] sequence = {1, 2, 3};
replace(3, sequence);
print();
Console.WriteLine();
}
}
// The elements are stored in a linked list, in their current order.
// The dummy node sits before the first element, and tail is the last node.
const dummy = { val: 0, next: null };
let tail = dummy;
// Inserts an integer at the end.
function insert(x) {
const node = { val: x, next: null };
tail.next = node;
tail = node;
}
// Prints the elements of the data structure.
function print() {
for (let cur = dummy.next; cur !== null; cur = cur.next)
process.stdout.write(cur.val + " ");
}
// Replaces the first occurrence of x with the given sequence.
function replace(x, sequence) {
// Find the node just before the first occurrence of x.
let prev = dummy;
while (prev.next !== null && prev.next.val !== x)
prev = prev.next;
const target = prev.next;
if (target === null)
return;
// Remove the first occurrence of x, and insert the sequence at the same position.
const after = target.next;
let cur = prev;
for (const val of sequence) {
cur.next = { val: val, next: null };
cur = cur.next;
}
cur.next = after;
// If the removed node was the last one, the tail moves to the last node of the sequence.
if (after === null)
tail = cur;
}
// Driver Code
insert(3);
insert(10);
print();
console.log();
insert(3);
const sequence = [1, 2, 3];
replace(3, sequence);
print();
console.log();
Output
3 10 1 2 3 10 3
Time Complexity: insert() - O(1), print() - O(n), replace() - O(n + m)
Space Complexity: O(n + m), where n is the number of elements in the data structure and m is the size of the sequence.