Find the Largest Multiple of 3 (Using Queue)


In this problem, we will find the largest multiple of 3 using the array elements.

The naïve approach is that generate all possible combinations of array elements and check whether it is divisible by 3. In this way, keep track of the maximum possible multiple of 3.

The efficient approach is using three queues. We can use queues to store elements based on the remainder after dividing it into 3. After that, we can remove some elements from the queue to make a multiple of 3 from the remaining array elements.

Problem statement − We have given an array containing N positive integer elements. We need to find the largest multiple of 3 by using the multiple elements of the array.

Sample examples

Input

nums = {9, 6, 2, 3, 8, 2, 1}

Output

9 8 6 3 2 2

Explanation − Here, we have taken all array elements except ‘1’ to create the largest multiple of 3.

Input

nums = {9, 6, 9, 3, 3, 9}

Output

9 9 9 6 3 3

Explanation − Here, we have taken all array elements as they are divisible by 3.

Input

nums = {7, 6, 3, 7}

Output

6 3

Explanation − Here, we need to remove 7 and 7 from the array to get the largest multiple of 3.

Approach 1

In this approach, we will use the bit manipulation technique to get all possible combinations of array elements. We will check whether each combination is a multiple of 3. If yes, we will compare it with the previous maximum combination and update it if the current combination is larger.

Algorithm

Step 1 − Sort the array using the sort() method in decreasing order.

Step 2 − Define the ‘largestNum’ vector to store the maximum possible combination.

Step 3 − Use the loop to traverse from 1 to 2N, as we have 2 choices for each array element. Either we can select the current element or leave it. So, we have total 2N combinations.

Step 4 − In the loop, define the ‘temp’ vector to store the current combination. Furthermore, traverse the array elements. If the pth bit in the m is ‘1’, insert the nums[p] into the ‘temp’ list.

Step 5 − Next, execute the checkForMul3() function to check whether the current combination is a multiple of 3.

Step 5.1 − In the checkForMul3() function, take some of all elements, and return true if the sum is divisible by 3. Otherwise, return false.

Step 6 − If the checkForMul3() function returns true, follow the steps below.

Step 6.1 − If the size of the temp is greater than the largestNum, update the largestNum with the temp.

Step 6.2 − If the size of the temp is equal to the largestNum, traverse both lists and compare each element of both lists.

Step 6.3 − If any index, temp[p] is greater than the largestNum[q], update largestNum with the temp, and break the loop. Also, if any index temp[p] is less than the largestNum[q], break the loop.

Step 7 − Return the ‘largestNum’ list.

Example

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool checkForMulOf3(const vector<int> &temp) {
    int s = 0;
    for (int num : temp) {
        s += num;
    }
    // Return true if the sum is divisible by 3
    return (s % 3 == 0);
}
vector<int> GetLargestMul3(vector<int> &nums) {
    // Sort in reverse order
    sort(nums.begin(), nums.end(), greater<int>());
    vector<int> largestNum;
    // Using bit manipulation technique
    for (int m = 1; m < (1 << nums.size()); m++) {
        vector<int> temp;
        // Take array elements according to the set-bits position
        for (int p = 0; p < nums.size(); p++) {
            if (m & (1 << p)) {
                temp.push_back(nums[p]);
            }
        }
        // When a new subset is multiple of 3
        if (checkForMulOf3(temp)) {
            // When the size of temp is greater than largestNum
            if (temp.size() > largestNum.size()) {
                largestNum = temp;
            } else if (temp.size() == largestNum.size()) {
                for (int p = 0; p < temp.size(); p++) {
                    if (temp[p] > largestNum[p]) {
                        largestNum = temp;
                        break;
                    } else if (temp[p] <largestNum[p]) { 
                        break;
                    }
                }
            }
        }
    }
    return largestNum;
}
int main() {
    vector<int> nums = {9, 6, 2, 3, 8, 2, 1};
    vector<int> largestMultiple = GetLargestMul3(nums);
    if (largestMultiple.size() > 0) {
        cout << "The largest multiple of 3: ";
        for (int num : largestMultiple) {
            cout << num << " ";
        }
    } else {
        cout << "It is not possible to find multiple of 3.";
    }
    cout << endl;
    return 0;
}

Output

The largest multiple of 3: 9 8 6 3 2 2

Time complexity − O(N*2N), to get all possible array combinations and take the sum of its elements.

Space complexity − O(N) to store array elements into the ‘temp’ list.

Approach 2

In this approach, we will use the three queues to store the array elements according to its reminder after dividing it by 3. After that, we will remove array elements from the particular queue based on the total sum of array elements.

Algorithm

Step 1 − Use the sort() method to sort the array.

Step 2 − Define three queues named ‘que0’, ‘que1’, and ‘que2’.

Step 3 − Traverse the array, and insert its elements into the queue. If nums[p] % 3 is 0, insert it into the que0. If nums[p] % 3 is 1, insert the array element into the que1. Otherwise, insert the array element into the que2. Also, store the sum of elements in the nums_sum variable.

Step 4 − If num_sum % 3 is 1, remove 1 element from the que1. If que1 is empty, remove 2 elements from the que2 if the size of the que2 is greater than or equal to 2. Otherwise, return 0.

Step 5 − If the num_sum % 3 is 2, remove 2 elements from the que2 if que2 is not empty. Otherwise, remove 2 elements from the que1 if it contains more than 2 elements. Else, return 0.

Step 6 − Create a temp[] array and insert elements of all queues into the temp array. After that, sort the temp array in decreasing order.

Step 7 − Print array elements.

Example

#include <bits/stdc++.h>
using namespace std;

int GetLargestMul3(int nums[], int size) {
    // Sort array in increasing order
    sort(nums, nums + size);
    // Definining 3 queues
    queue<int> que0, que1, que2;
    // Insert elements in these queues according to reminder and sum them
    int p, num_sum;
    for (p = 0, num_sum = 0; p < size; ++p) {
        // Sum numbers
        num_sum += nums[p];
        // Insert in queues
        if ((nums[p] % 3) == 0)
            que0.push(nums[p]);
        else if ((nums[p] % 3) == 1) {
            que1.push(nums[p]);
        } else {
            que2.push(nums[p]);
        }
    }
    // When sum%3 == 1
    if ((num_sum % 3) == 1) {
        // Pop out one item from que1
        if (!que1.empty()) {
            que1.pop();
        }
        // Pop out two items from que2
        else {
            if (que2.size() >= 2) {
                que2.pop();
                que2.pop();
            } else {
                return 0;
            }
        }
    }
    // When sum%3 == 2
    else if ((num_sum % 3) == 2) {
        // Pop out one item from que2
        if (!que2.empty())
            que2.pop();
        // Pop out two items from que1
        else {
            if (que1.size() >= 2) {
                que1.pop();
                que1.pop();
            } else {
                return 0;
            }
        }
    }
    int temp[size], top = 0;
    // Insert elements of the first queue in the array
    while (!que0.empty()) {
        temp[top++] = que0.front();
        que0.pop();
    }
    // Insert elements of the second queue in the array
    while (!que1.empty()) {
        temp[top++] = que1.front();
        que1.pop();
    }
    // Insert elements of the third queue in the array
    while (!que2.empty()) {
        temp[top++] = que2.front();
        que2.pop();
    }
    // Sort the array in reverse order
    sort(temp, temp + top, greater<int>());
    cout << "The largest divisible of 3 we can create is - ";
    // Show number
    for (int p = 0; p < top; ++p)
        cout << temp[p] << " ";

    return top;
}
int main() {
    int nums[] = {9, 6, 2, 3, 8, 2, 1};
    int size = sizeof(nums) / sizeof(nums[0]);
    if (GetLargestMul3(nums, size) == 0)
        cout << "It is not possible to find the largest multiple of 3.";
    return 0;
}

Output

The largest divisible of 3 we can create is - 9 8 6 3 2 2

Time complexity − O(N)

Space complexity − O(N) for storing elements in the queue.

Updated on: 02-Aug-2023

76 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements