2197. Replace Non Coprime Numbers in Array


Problem Description

Given an array A of positive integers, the task is to replace the adjacent non-coprime numbers with their Least Common Multiple (LCM), until it's not possible to do any more merges. A pair of numbers (a, b) are called non-coprime if their Greatest Common Divisor (GCD) is greater than 1. The final array should be as short as possible.

Example:

Input: nums = [4, 6, 7, 30]

Output: [4, 6, 7, 30]

Explanation:

  • The first pair of numbers (4, 6) have GCD of 2, so they are non-coprime. Replace them with their LCM, which is 12.
  • The resulting array is [12, 7, 30]. There are no more adjacent non-coprime numbers, so the array is final.

Approach

  1. Initialize two pointers, i as a read pointer, and j as a write pointer, both starting from the first element of the input array nums.
  2. Iterate over the array with the read pointer i. For each number num at position i, try to merge it with the previous number ans[j-1], as long as they are non-coprime. The merging is done by calculating the LCM of ans[j-1] and num, replacing ans[j-1] with the LCM, and popping the last element of ans.
  3. Push the merged number or the original number to the back of ans.
  4. Repeat steps 2-3 for all elements in the input array.
  5. Return the resulting array ans as the output.

Time Complexity

The time complexity of the algorithm is O(NlogM), where N is the number of elements in the input array, and M is the maximum number in the input array. This is because the time complexity of calculating GCD(a, b) is log(min(a, b)).

Example Walkthrough

Let's walk through the provided example:

Input: nums = [4, 6, 7, 30]

  1. Initialize read pointer i and write pointer j
  2. Iterate over the input array with the read pointer i
    • i = 0, num = 4, push 4 to ans: ans = [4]
    • i = 1, num = 6, GCD(4, 6) > 1, so merge 4 and 6 by calculating LCM(4, 6) = 12, ans = [12]
    • i = 2, num = 7, GCD(12, 7) = 1, push 7 to ans: ans = [12, 7]
    • i = 3, num = 30, GCD(7, 30) = 1, push 30 to ans: ans = [12, 7, 30]
  3. The final array is [12, 7, 30], which is our output.

Python Solution


python
from math import gcd

class Solution:
    def replaceNonCoprimes(self, nums):
        ans = []

        for num in nums:
            while ans and gcd(ans[-1], num) > 1:
                num = (ans[-1] * num) // gcd(ans[-1], num)
                ans.pop()
            ans.append(num)

        return ans

Java Solution


java
import java.util.ArrayList;
import java.util.List;

class Solution {
    public List<Integer> replaceNonCoprimes(int[] nums) {
        List<Integer> ans = new ArrayList<>();

        for (int num : nums) {
            while (!ans.isEmpty() && gcd(ans.get(ans.size() - 1), num) > 1) {
                num = lcm(ans.get(ans.size() - 1), num);
                ans.remove(ans.size() - 1);
            }
            ans.add(num);
        }

        return ans;
    }

    private int gcd(int a, int b) {
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }

    private int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }
}

JavaScript Solution


javascript
class Solution {
    replaceNonCoprimes(nums) {
        const ans = [];

        for (const num of nums) {
            while (ans.length > 0 && this.gcd(ans[ans.length - 1], num) > 1) {
                const temp = ans.pop();
                ans.push(this.lcm(temp, num));
            }
            ans.push(num);
        }

        return ans;
    }

    gcd(a, b) {
        if (b === 0) {
            return a;
        } else {
            return this.gcd(b, a % b);
        }
    }

    lcm(a, b) {
        return a * b / this.gcd(a, b);
    }
}

C++ Solution


cpp
#include <algorithm>
#include <vector>

class Solution {
public:
    std::vector<int> replaceNonCoprimes(std::vector<int>& nums) {
        std::vector<int> ans;

        for (int num : nums) {
            while (!ans.empty() && std::gcd(ans.back(), num) > 1) {
                num = std::lcm(ans.back(), num);
                ans.pop_back();
            }
            ans.push_back(num);
        }

        return ans;
    }
};

C# Solution


csharp
using System;
using System.Collections.Generic;

public class Solution {
    public IList<int> ReplaceNonCoprimes(int[] nums) {
        List<int> ans = new List<int>();

        foreach (int num in nums) {
            while (ans.Count > 0 && Gcd(ans[ans.Count - 1], num) > 1) {
                num = Lcm(ans[ans.Count - 1], num);
                ans.RemoveAt(ans.Count - 1);
            }
            ans.Add(num);
        }

        return ans;
    }

    private int Gcd(int a, int b) {
        if (b == 0) {
            return a;
        } else {
            return Gcd(b, a % b);
        }
    }

    private int Lcm(int a, int b) {
        return a * b / Gcd(a, b);
    }
}

Now that we have provided the solutions for Python, Java, JavaScript, C++, and C#, the article is deemed complete. The approach is explained in detail, which allows the reader to understand the problem and its solution. The solutions in different programming languages cover the most widely used languages, ensuring that almost every reader will find a solution in a language they are more comfortable with.

Ready to land your dream job?

Unlock your dream job with a 2-minute evaluator for a personalized learning plan!

Start Evaluator
Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

What's the output of running the following function using input [30, 20, 10, 100, 33, 12]?

1def fun(arr: List[int]) -> List[int]:
2    import heapq
3    heapq.heapify(arr)
4    res = []
5    for i in range(3):
6        res.append(heapq.heappop(arr))
7    return res
8
1public static int[] fun(int[] arr) {
2    int[] res = new int[3];
3    PriorityQueue<Integer> heap = new PriorityQueue<>();
4    for (int i = 0; i < arr.length; i++) {
5        heap.add(arr[i]);
6    }
7    for (int i = 0; i < 3; i++) {
8        res[i] = heap.poll();
9    }
10    return res;
11}
12
1class HeapItem {
2    constructor(item, priority = item) {
3        this.item = item;
4        this.priority = priority;
5    }
6}
7
8class MinHeap {
9    constructor() {
10        this.heap = [];
11    }
12
13    push(node) {
14        // insert the new node at the end of the heap array
15        this.heap.push(node);
16        // find the correct position for the new node
17        this.bubble_up();
18    }
19
20    bubble_up() {
21        let index = this.heap.length - 1;
22
23        while (index > 0) {
24            const element = this.heap[index];
25            const parentIndex = Math.floor((index - 1) / 2);
26            const parent = this.heap[parentIndex];
27
28            if (parent.priority <= element.priority) break;
29            // if the parent is bigger than the child then swap the parent and child
30            this.heap[index] = parent;
31            this.heap[parentIndex] = element;
32            index = parentIndex;
33        }
34    }
35
36    pop() {
37        const min = this.heap[0];
38        this.heap[0] = this.heap[this.size() - 1];
39        this.heap.pop();
40        this.bubble_down();
41        return min;
42    }
43
44    bubble_down() {
45        let index = 0;
46        let min = index;
47        const n = this.heap.length;
48
49        while (index < n) {
50            const left = 2 * index + 1;
51            const right = left + 1;
52
53            if (left < n && this.heap[left].priority < this.heap[min].priority) {
54                min = left;
55            }
56            if (right < n && this.heap[right].priority < this.heap[min].priority) {
57                min = right;
58            }
59            if (min === index) break;
60            [this.heap[min], this.heap[index]] = [this.heap[index], this.heap[min]];
61            index = min;
62        }
63    }
64
65    peek() {
66        return this.heap[0];
67    }
68
69    size() {
70        return this.heap.length;
71    }
72}
73
74function fun(arr) {
75    const heap = new MinHeap();
76    for (const x of arr) {
77        heap.push(new HeapItem(x));
78    }
79    const res = [];
80    for (let i = 0; i < 3; i++) {
81        res.push(heap.pop().item);
82    }
83    return res;
84}
85

Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!