📜  从数字数组中找到3的最大倍数|集合2(在O(n)时间和O(1)空间中)

📅  最后修改于: 2021-04-24 14:32:36             🧑  作者: Mango

给定一个数字数组(包含0到9的元素)。查找可以从数组的某些或全部数字中得出的最大数字,该数字可以被3整除。同一元素在数组中可能出现多次,但数组中的每个元素只能使用一次。
例子:

Input : arr[] = {5, 4, 3, 1, 1} 
Output : 4311

Input : Arr[] = {5, 5, 5, 7} 
Output : 555 

提问人: Google面试

我们已经讨论了基于队列的解决方案。两种解决方案(在上一则和这篇文章中都有讨论)都是基于一个事实,即当且仅当该数字的位数之和可被3整除时,该数字才可被3整除。

例如,让我们考虑555,它可以被3整除,因为数字的总和是5 + 5 + 5 = 15,可以被3整除。如果数字的总和不能被3整除,那么余数应该是1或2。
如果我们得到余数“ 1”或“ 2”,则必须删除最多两位数以使数字可被3整除:

  1. 如果余数为’1’:我们必须删除余数为’1’的一位数字,或者我们必须删除余数为’2’的两位数字(2 + 2 => 4%3 =>’1’)
  2. 如果剩余数为’2’:。我们必须删除剩余数为’2’的一位数字,或者我们必须删除剩余数为’1’的两位数字(1 +1 => 2%3 => 2)。

例子 :

Input : arr[] = 5, 5, 5, 7 
Sum of digits = 5 + 5 + 5 + 7 = 22
Remainder = 22 % 3 = 1 
We remove smallest single digit that 
has remainder '1'. We remove 7 % 3 = 1 
So largest number divisible by 3 is : 555

Let's take an another example :
Input : arr[]  = 4 , 4 , 1 , 1 , 1 , 3
Sum of digits  = 4 + 4 + 1 + 1 + 1 + 3 = 14
Reminder = 14 % 3 = 2 
We have to remove the smallest digit that 
has remainder ' 2 ' or two digits that have
remainder '1'. Here there is no digit with 
reminder '2', so we have to remove two smallest 
digits that have remainder '1'. The digits are : 
1, 1. So largest number divisible by 3 is 4 4 3 1 

以下是上述想法的实现。

C++
// C++ program to find the largest number
// that can be mode from elements of the
// array and is divisible by 3
#include
using namespace std;
  
// Number of digits
#define MAX_SIZE 10
  
// function to sort array of digits using
// counts
void sortArrayUsingCounts(int arr[], int n)
{
    // Store count of all elements
    int count[MAX_SIZE] = {0};
    for (int i = 0; i < n; i++)
        count[arr[i]]++;
  
    // Store
    int index = 0;
    for (int i = 0; i < MAX_SIZE; i++)
        while (count[i] > 0)
            arr[index++] = i, count[i]--;
}
  
// Remove elements from arr[] at indexes ind1 and ind2
bool removeAndPrintResult(int arr[], int n, int ind1,
                                        int ind2 = -1)
{
    for (int i = n-1; i >=0; i--)
        if (i != ind1 && i != ind2)
            cout << arr[i] ;
}
  
// Returns largest multiple of 3 that can be formed
// using arr[] elements.
bool largest3Multiple(int arr[], int n)
{
    // Sum of all array element
    int sum = accumulate(arr, arr+n, 0);
  
    // Sum is divisible by 3 , no need to
    // delete an element
    if (sum%3 == 0)
        return true ;
  
    // Sort array element in increasing order
    sortArrayUsingCounts(arr, n);
  
    // Find reminder
    int remainder = sum % 3;
  
    // If remainder is '1', we have to delete either
    // one element of remainder '1' or two elements
    // of remainder '2'
    if (remainder == 1)
    {
        int rem_2[2];
        rem_2[0] = -1, rem_2[1] = -1;
  
        // Traverse array elements
        for (int i = 0 ; i < n ; i++)
        {
            // Store first element of remainder '1'
            if (arr[i]%3 == 1)
            {
                removeAndPrintResult(arr, n, i);
                return true;
            }
  
            if (arr[i]%3 == 2)
            {
                // If this is first occurrence of remainder 2
                if (rem_2[0] == -1)
                    rem_2[0] = i;
  
                // If second occurrence
                else if (rem_2[1] == -1)
                    rem_2[1] = i;
            }
        }
  
        if (rem_2[0] != -1 && rem_2[1] != -1)
        {
            removeAndPrintResult(arr, n, rem_2[0], rem_2[1]);
            return true;
        }
    }
  
    // If remainder is '2', we have to delete either
    // one element of remainder '2' or two elements
    // of remainder '1'
    else if (remainder == 2)
    {
        int rem_1[2];
        rem_1[0] = -1, rem_1[1] = -1;
  
        // traverse array elements
        for (int i = 0; i < n; i++)
        {
            // store first element of remainder '2'
            if (arr[i]%3 == 2)
            {
                removeAndPrintResult(arr, n, i);
                return true;
            }
  
            if (arr[i]%3 == 1)
            {
                // If this is first occurrence of remainder 1
                if (rem_1[0] == -1)
                    rem_1[0] = i;
  
                // If second occurrence
                else if (rem_1[1] == -1)
                    rem_1[1] = i;
            }
        }
  
        if (rem_1[0] != -1 && rem_1[1] != -1)
        {
            removeAndPrintResult(arr, n, rem_1[0], rem_1[1]);
            return true;
        }
    }
  
    cout << "Not possible";
    return false;
}
  
// Driver code
int main()
{
    int arr[] = {4 , 4 , 1 , 1 , 1 , 3} ;
    int n = sizeof(arr)/sizeof(arr[0]);
    largest3Multiple(arr, n);
    return 0;
}


Java
// Java program to find the largest number
// that can be mode from elements of the
// array and is divisible by 3
import java.util.*;
  
class GFG 
{
  
    // Number of digits
    static int MAX_SIZE = 10;
  
    // function to sort array of digits using
    // counts
    static void sortArrayUsingCounts(int arr[], 
                                     int n)
    {
        // Store count of all elements
        int[] count = new int[MAX_SIZE];
        for (int i = 0; i < n; i++) 
        {
            count[arr[i]]++;
        }
  
        // Store
        int index = 0;
        for (int i = 0; i < MAX_SIZE; i++) 
        {
            while (count[i] > 0) 
            {
                arr[index++] = i;
                count[i]--;
            }
        }
    }
  
    // Remove elements from arr[]
    // at indexes ind1 and ind2
    static void removeAndPrintResult(int arr[], int n, 
                                     int ind1, int ind2)
    {
        for (int i = n - 1; i >= 0; i--)
        {
            if (i != ind1 && i != ind2) 
            {
                System.out.print(arr[i]);
            }
        }
    }
  
    // Returns largest multiple of 3 
    // that can be formed using
    // arr[] elements.
    static boolean largest3Multiple(int arr[], 
                                    int n)
    {
        // Sum of all array element
        int sum = accumulate(arr, 0, n);
  
        // If sum is divisible by 3, 
        // no need to delete an element
        if (sum % 3 == 0) 
        {
            return true;
        }
  
        // Sort array element in increasing order
        sortArrayUsingCounts(arr, n);
  
        // Find reminder
        int remainder = sum % 3;
  
        // If remainder is '1', we have to 
        // delete either one element of 
        // remainder '1' or two elements of 
        // remainder '2'
        if (remainder == 1)
        {
            int[] rem_2 = new int[2];
            rem_2[0] = -1;
            rem_2[1] = -1;
  
            // Traverse array elements
            for (int i = 0; i < n; i++) 
            {
                  
                // Store first element of remainder '1'
                if (arr[i] % 3 == 1)
                {
                    removeAndPrintResult(arr, n, i, -1);
                    return true;
                }
  
                if (arr[i] % 3 == 2)
                {
                      
                    // If this is first occurrence
                    // of remainder 2
                    if (rem_2[0] == -1)
                    {
                        rem_2[0] = i;
                    }
                      
                    // If second occurrence
                    else if (rem_2[1] == -1) 
                    {
                        rem_2[1] = i;
                    }
                }
            }
  
            if (rem_2[0] != -1 && 
                rem_2[1] != -1) 
            {
                removeAndPrintResult(arr, n, rem_2[0], 
                                             rem_2[1]);
                return true;
            }
        } 
          
        // If remainder is '2', we have to 
        // delete either one element of 
        // remainder '2' or two elements of
        // remainder '1'
        else if (remainder == 2) 
        {
            int[] rem_1 = new int[2];
            rem_1[0] = -1;
            rem_1[1] = -1;
  
            // traverse array elements
            for (int i = 0; i < n; i++) 
            {
                  
                // store first element of remainder '2'
                if (arr[i] % 3 == 2) 
                {
                    removeAndPrintResult(arr, n, i, -1);
                    return true;
                }
  
                if (arr[i] % 3 == 1) 
                {
                      
                    // If this is first occurrence
                    // of remainder 1
                    if (rem_1[0] == -1) 
                    {
                        rem_1[0] = i;
                    } 
                      
                    // If second occurrence
                    else if (rem_1[1] == -1) 
                    {
                        rem_1[1] = i;
                    }
                }
            }
  
            if (rem_1[0] != -1 && 
                rem_1[1] != -1)
            {
                removeAndPrintResult(arr, n, rem_1[0], 
                                             rem_1[1]);
                return true;
            }
        }
        System.out.print("Not possible");
        return false;
    }
  
    static int accumulate(int[] arr,
                          int start, 
                          int end) 
    {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) 
        {
            sum += arr[i];
        }
        return sum;
    }
      
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = {4, 4, 1, 1, 1, 3};
        int n = arr.length;
        largest3Multiple(arr, n);
    }
}
  
// This code is contributed
// by Princi Singh


Python3
# Python3 program to find the largest number
# that can be mode from elements of the
# array and is divisible by 3
  
# Number of digits
MAX_SIZE = 10
  
# function to sort array of digits using
# counts
def sortArrayUsingCounts(arr, n):
  
    # Store count of all elements
    count = [0]*MAX_SIZE
    for i in range(n):
        count[arr[i]] += 1
  
    # Store
    index = 0
    for i in range(MAX_SIZE):
        while count[i] > 0:
            arr[index] = i
            index += 1
            count[i] -= 1
  
  
# Remove elements from arr[] at indexes ind1 and ind2
def removeAndPrintResult(arr, n, ind1, ind2=-1):
    for i in range(n-1, -1, -1):
        if i != ind1 and i != ind2:
            print(arr[i], end="")
  
  
# Returns largest multiple of 3 that can be formed
# using arr[] elements.
def largest3Multiple(arr, n):
  
    # Sum of all array element
    s = sum(arr)
  
    # Sum is divisible by 3, no need to
    # delete an element
    if s % 3 == 0:
        return True
  
    # Sort array element in increasing order
    sortArrayUsingCounts(arr, n)
  
    # Find reminder
    remainder = s % 3
  
    # If remainder is '1', we have to delete either
    # one element of remainder '1' or two elements
    # of remainder '2'
    if remainder == 1:
        rem_2 = [0]*2
        rem_2[0] = -1; rem_2[1] = -1
  
        # Traverse array elements
        for i in range(n):
  
            # Store first element of remainder '1'
            if arr[i] % 3 == 1:
                removeAndPrintResult(arr, n, i)
                return True
  
            if arr[i] % 3 == 2:
  
                # If this is first occurrence of remainder 2
                if rem_2[0] == -1:
                    rem_2[0] = i
  
                # If second occurrence
                elif rem_2[1] == -1:
                    rem_2[1] = i
  
        if rem_2[0] != -1 and rem_2[1] != -1:
            removeAndPrintResult(arr, n, rem_2[0], rem_2[1])
            return True
  
    # If remainder is '2', we have to delete either
    # one element of remainder '2' or two elements
    # of remainder '1'
    elif remainder == 2:
        rem_1 = [0]*2
        rem_1[0] = -1; rem_1[1] = -1
  
        # traverse array elements
        for i in range(n):
  
            # store first element of remainder '2'
            if arr[i] % 3 == 2:
                removeAndPrintResult(arr, n, i)
                return True
  
            if arr[i] % 3 == 1:
  
                # If this is first occurrence of remainder 1
                if rem_1[0] == -1:
                    rem_1[0] = i
                  
                # If second occurrence
                elif rem_1[1] == -1:
                    rem_1[1] = i
                      
        if rem_1[0] != -1 and rem_1[1] != -1:
            removeAndPrintResult(arr, n, rem_1[0], rem_1[1])
            return True
  
    print("Not possible")
    return False
  
  
# Driver code
if __name__ == "__main__":
  
    arr = [4, 4, 1, 1, 1, 3]
    n = len(arr)
    largest3Multiple(arr, n)
  
# This code is contributed by
# sanjeev2552


C#
// C# program to find the largest number
// that can be mode from elements of the
// array and is divisible by 3
using System;
      
class GFG 
{
  
    // Number of digits
    static int MAX_SIZE = 10;
  
    // function to sort array of digits using
    // counts
    static void sortArrayUsingCounts(int []arr, 
                                     int n)
    {
        // Store count of all elements
        int[] count = new int[MAX_SIZE];
        for (int i = 0; i < n; i++) 
        {
            count[arr[i]]++;
        }
  
        // Store
        int index = 0;
        for (int i = 0; i < MAX_SIZE; i++) 
        {
            while (count[i] > 0) 
            {
                arr[index++] = i;
                count[i]--;
            }
        }
    }
  
    // Remove elements from arr[]
    // at indexes ind1 and ind2
    static void removeAndPrintResult(int []arr, int n, 
                                     int ind1, int ind2)
    {
        for (int i = n - 1; i >= 0; i--)
        {
            if (i != ind1 && i != ind2) 
            {
                Console.Write(arr[i]);
            }
        }
    }
  
    // Returns largest multiple of 3 
    // that can be formed using
    // arr[] elements.
    static Boolean largest3Multiple(int []arr, 
                                    int n)
    {
        // Sum of all array element
        int sum = accumulate(arr, 0, n);
  
        // If sum is divisible by 3, 
        // no need to delete an element
        if (sum % 3 == 0) 
        {
            return true;
        }
  
        // Sort array element in increasing order
        sortArrayUsingCounts(arr, n);
  
        // Find reminder
        int remainder = sum % 3;
  
        // If remainder is '1', we have to 
        // delete either one element of 
        // remainder '1' or two elements of 
        // remainder '2'
        if (remainder == 1)
        {
            int[] rem_2 = new int[2];
            rem_2[0] = -1;
            rem_2[1] = -1;
  
            // Traverse array elements
            for (int i = 0; i < n; i++) 
            {
                  
                // Store first element of remainder '1'
                if (arr[i] % 3 == 1)
                {
                    removeAndPrintResult(arr, n, i, -1);
                    return true;
                }
  
                if (arr[i] % 3 == 2)
                {
                      
                    // If this is first occurrence
                    // of remainder 2
                    if (rem_2[0] == -1)
                    {
                        rem_2[0] = i;
                    }
                      
                    // If second occurrence
                    else if (rem_2[1] == -1) 
                    {
                        rem_2[1] = i;
                    }
                }
            }
  
            if (rem_2[0] != -1 && 
                rem_2[1] != -1) 
            {
                removeAndPrintResult(arr, n, rem_2[0], 
                                              rem_2[1]);
                return true;
            }
        } 
          
        // If remainder is '2', we have to 
        // delete either one element of 
        // remainder '2' or two elements of
        // remainder '1'
        else if (remainder == 2) 
        {
            int[] rem_1 = new int[2];
            rem_1[0] = -1;
            rem_1[1] = -1;
  
            // traverse array elements
            for (int i = 0; i < n; i++) 
            {
                  
                // store first element of remainder '2'
                if (arr[i] % 3 == 2) 
                {
                    removeAndPrintResult(arr, n, i, -1);
                    return true;
                }
  
                if (arr[i] % 3 == 1) 
                {
                      
                    // If this is first occurrence
                    // of remainder 1
                    if (rem_1[0] == -1) 
                    {
                        rem_1[0] = i;
                    } 
                      
                    // If second occurrence
                    else if (rem_1[1] == -1) 
                    {
                        rem_1[1] = i;
                    }
                }
            }
  
            if (rem_1[0] != -1 && 
                rem_1[1] != -1)
            {
                removeAndPrintResult(arr, n, rem_1[0], 
                                             rem_1[1]);
                return true;
            }
        }
        Console.Write("Not possible");
        return false;
    }
  
    static int accumulate(int[] arr,
                          int start, 
                          int end) 
    {
        int sum = 0;
        for (int i = 0; i < arr.Length; i++) 
        {
            sum += arr[i];
        }
        return sum;
    }
      
    // Driver code
    public static void Main(String[] args)
    {
        int []arr = {4, 4, 1, 1, 1, 3};
        int n = arr.Length;
        largest3Multiple(arr, n);
    }
}
  
// This code is contributed by 29AjayKumar


输出:

4431