Given an array arr[] of digits (values are from 0 to 9), find the minimum possible sum of two numbers formed using all digits of the array.
Note: We need to return the minimum possible sum as a string.
Examples:
Input: arr[] = [6, 8, 4, 5, 2, 3, 0]
Output: "604"
Explanation: The minimum sum is formed by numbers 0358 and 246.Input: arr[] = [5, 3, 0, 7, 4]
Output: "82"
Explanation: The minimum sum is formed by numbers 35 and 047.
Table of Content
[Naive Approach] Using Sorting - O(n log n) time and O(n) space
A minimum number will be formed from set of digits when smallest digit appears at most significant position and next smallest digit appears at next most significant position and so on. The idea is to first sort the digits in increasing order so that smaller digits come first. Then, we form two numbers by alternately picking digits from the sorted array. This ensures that the smallest digits are placed at the most significant positions of both numbers, keeping them balanced in length and minimizing their sum.
Illustration:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
// Function to add two strings and return the result
string addString(string &s1, string &s2) {
int i = s1.length() - 1 ;
int j = s2.length() - 1 ;
// initial carry is zero
int carry = 0 ;
// we will calculate and store the
// resultant sum in reverse order in res
string res = "" ;
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry ;
if (i >= 0)
sum += (s1[i] - '0') ;
if (j >= 0)
sum += (s2[j] - '0') ;
res.push_back(sum % 10 + '0') ;
carry = sum / 10 ;
i-- ;
j-- ;
}
// remove leading zeroes which are currently
// at the back due to reversed string res
while (!res.empty() && res.back() == '0')
res.pop_back() ;
// reverse our final string
reverse(res.begin(), res.end()) ;
return res ;
}
// Function to find and return minimum sum of
// two numbers formed from digits of the array.
string minSum(vector<int> &arr) {
sort(arr.begin(), arr.end()) ;
// Two String for storing the two minimum numbers
string s1 = "", s2 = "" ;
for (int i = 0; i < arr.size(); i++) {
if (i % 2 == 0)
s1.push_back(arr[i] + '0') ;
else
s2.push_back(arr[i] + '0') ;
}
return addString(s1, s2);
}
int main() {
vector<int> arr = {6, 8, 4, 5, 2, 3, 0};
cout << minSum(arr);
return 0;
}
import java.util.Arrays;
class GfG {
// Function to add two numeric strings and return the sum as a string
static String addString(String s1, String s2) {
int i = s1.length() - 1;
int j = s2.length() - 1;
int carry = 0;
String res = "";
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry;
if (i >= 0)
sum += s1.charAt(i--) - '0';
if (j >= 0)
sum += s2.charAt(j--) - '0';
res = (sum % 10) + res;
carry = sum / 10;
}
// Remove leading zeros
res = res.replaceFirst("^0+(?!$)", "");
return res;
}
// Function to find minimum sum of two numbers formed from digits
static String minSum(int[] arr) {
Arrays.sort(arr);
String s1 = "", s2 = "";
for (int i = 0; i < arr.length; i++) {
if (i % 2 == 0)
// add to first number
s1 += arr[i];
else
// add to second number
s2 += arr[i];
}
return addString(s1, s2);
}
public static void main(String[] args) {
int[] arr = {6, 8, 4, 5, 2, 3, 0};
System.out.println(minSum(arr));
}
}
# Function to add two numbers and return the result
def addNumbers(l1, l2):
i = len(l1) - 1
j = len(l2) - 1
# initial carry is zero
carry = 0
# we will calculate and store the
# resultant sum in reverse order in res
res = []
while i >= 0 or j >= 0 or carry > 0:
total = carry
if i >= 0:
total += l1[i]
if j >= 0:
total += l2[j]
res.append(str(total % 10))
carry = total // 10
i -= 1
j -= 1
# remove leading zeroes which are currently
# at the back due to reversed string res
while len(res) > 0 and res[-1] == '0':
res.pop()
# reverse our final result
res = res[::-1]
return ''.join(res)
# Function to find and return minimum sum of
# two numbers formed from digits of the array.
def minSum(arr):
arr.sort()
# Two Lists for storing the two minimum numbers
l1 = []
l2 = []
for i in range(len(arr)):
if i % 2 == 0:
l1.append(arr[i])
else:
l2.append(arr[i])
return addNumbers(l1, l2)
if __name__ == '__main__':
arr = [6, 8, 4, 5, 2, 3, 0]
print(minSum(arr))
using System;
class GfG{
// Function to add two numeric strings and return the result as a string
static string addString(string s1, string s2){
int i = s1.Length - 1;
int j = s2.Length - 1;
int carry = 0;
string res = "";
// Loop until both strings are processed and no carry remains
while (i >= 0 || j >= 0 || carry > 0){
int sum = carry;
// Add current digit from s1 if any
if (i >= 0) sum += s1[i--] - '0';
// Add current digit from s2 if any
if (j >= 0) sum += s2[j--] - '0';
// Add least significant digit of sum to result
res = (sum % 10) + res;
carry = sum / 10;
}
// Remove any leading zeros (except when result is "0")
int k = 0;
while (k < res.Length - 1 && res[k] == '0') k++;
return res.Substring(k);
}
// Function to find and return minimum possible sum of two numbers
// formed by using all digits in the array
static string minSum(int[] arr){
// Sort the digits in ascending order
Array.Sort(arr);
string s1 = "";
string s2 = "";
// Distribute digits alternately between s1 and s2
for (int i = 0; i < arr.Length; i++)
{
if (i % 2 == 0)
s1 += arr[i];
else
s2 += arr[i];
}
// Add the two numbers and return their sum as a string
return addString(s1, s2);
}
static void Main(string[] args)
{
int[] arr = { 6, 8, 4, 5, 2, 3, 0 };
Console.WriteLine(minSum(arr));
}
}
// Function to add two lists and return the result
function addNumbers(l1, l2) {
let i = l1.length - 1;
let j = l2.length - 1;
// initial carry is zero
let carry = 0;
// we will calculate and store the
// resultant sum in reverse order in res
let res = [];
while (i >= 0 || j >= 0 || carry > 0) {
let sum = carry;
if (i >= 0)
sum += l1[i] - '0';
if (j >= 0)
sum += l2[j] - '0';
res.push(sum % 10);
carry = Math.floor(sum / 10);
i--;
j--;
}
// remove leading zeroes which are currently
// at the back due to reversed list res
while (res.length > 0 && res[res.length - 1] === 0)
res.pop();
// reverse our final list and convert it to a string
return res.reverse().join('');
}
// Function to find and return minimum sum of
// two numbers formed from digits of the array.
function minSum(arr) {
arr.sort((a, b) => a - b);
// Two lists for storing the two minimum numbers
let l1 = [], l2 = [];
for (let i = 0; i < arr.length; i++) {
if (i % 2 === 0)
l1.push(arr[i]);
else
l2.push(arr[i]);
}
return addNumbers(l1, l2);
}
// Driver Code
let arr = [6, 8, 4, 5, 2, 3, 0];
console.log(minSum(arr));
Output
604
[Expected Approach] Using Count Array - O(n) time and O(n) space
This approach uses a count array to store the frequency of digits from 0 to 9, avoiding the need for sorting. By traversing the count array from smallest to largest digit and alternately assigning digits to two numbers while avoiding leading zeros, we can efficiently construct the two numbers with minimum sum in linear time.
Algorithm:
- Create a count array to store frequency of digits (0–9).
- Traverse digits from 0 to 9 and alternately add digits that are present to
s1ands2. - Skip leading zeros while forming numbers.
- Add both numbers using string addition and return result.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// Function to add two strings and return the result
string addString(string &s1, string &s2) {
int i = s1.length() - 1;
int j = s2.length() - 1;
// initial carry is zero
int carry = 0;
// we will calculate and store the
// resultant sum in reverse order in res
string res = "";
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry;
if (i >= 0)
sum += (s1[i] - '0');
if (j >= 0)
sum += (s2[j] - '0');
res.push_back(sum % 10 + '0');
carry = sum / 10;
i--;
j--;
}
// remove leading zeroes which are currently
// at the back due to reversed string res
while (!res.empty() && res.back() == '0')
res.pop_back();
// reverse our final string
reverse(res.begin(), res.end());
return res;
}
// Function to find minimum sum using count array approach
string minSum(vector<int> &arr) {
// Count array to store frequency of each digit
vector<int> count(10, 0);
// Count occurrences of each digit
for (int num : arr) {
count[num]++;
}
// Two strings for storing the two minimum numbers
string s1 = "", s2 = "";
// Flag to alternate between s1 and s2
bool firstNum = true;
// Traverse count array from 0 to 9
for (int digit = 0; digit < 10; digit++) {
// Add digit to appropriate string
// while it has occurrences
while (count[digit]--) {
if (firstNum) {
// Avoid leading zeros for both numbers
if (!(s1.empty() && digit == 0))
s1.push_back(digit + '0');
firstNum = false;
} else {
if (!(s2.empty() && digit == 0))
s2.push_back(digit + '0');
firstNum = true;
}
}
}
// Handle case where s1 or s2 might be empty
if (s1.empty()) s1 = "0";
if (s2.empty()) s2 = "0";
return addString(s1, s2);
}
int main() {
vector<int> arr = {6, 8, 4, 5, 2, 3, 0};
cout << minSum(arr) << endl;
return 0;
}
import java.io.IOException;
class GfG {
// Function to add two strings and return the result
static String addString(String s1, String s2) {
int i = s1.length() - 1;
int j = s2.length() - 1;
// initial carry is zero
int carry = 0;
// we will calculate and store the
// resultant sum in reverse order in res
StringBuilder res = new StringBuilder();
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry;
if (i >= 0)
sum += (s1.charAt(i) - '0');
if (j >= 0)
sum += (s2.charAt(j) - '0');
res.append(sum % 10);
carry = sum / 10;
i--;
j--;
}
// remove leading zeroes which are currently
// at the back due to reversed string res
while (res.length() > 0 && res.charAt(res.length() - 1) == '0')
res.deleteCharAt(res.length() - 1);
// reverse our final string
res.reverse();
return res.length() == 0 ? "0" : res.toString();
}
// Function to find minimum sum using count array approach
static String minSum(int[] arr) {
// Count array to store frequency of each digit
int[] count = new int[10];
// Count occurrences of each digit
for (int num : arr) {
count[num]++;
}
// Two strings for storing the two minimum numbers
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
// Flag to alternate between s1 and s2
boolean firstNum = true;
// Traverse count array from 0 to 9
for (int digit = 0; digit < 10; digit++) {
// Add digit to appropriate string
// while it has occurrences
while (count[digit]-- > 0) {
if (firstNum) {
// Avoid leading zeros for both numbers
if (!(s1.length() == 0 && digit == 0))
s1.append(digit);
firstNum = false;
} else {
if (!(s2.length() == 0 && digit == 0))
s2.append(digit);
firstNum = true;
}
}
}
// Handle case where s1 or s2 might be empty
if (s1.length() == 0) s1.append("0");
if (s2.length() == 0) s2.append("0");
return addString(s1.toString(), s2.toString());
}
public static void main(String[] args) {
int[] arr = {6, 8, 4, 5, 2, 3, 0};
System.out.println(minSum(arr));
}
}
# Function to add two strings and return the result
def addString(s1, s2):
i = len(s1) - 1
j = len(s2) - 1
# initial carry is zero
carry = 0
# we will calculate and store the
# resultant sum in reverse order in res
res = []
while i >= 0 or j >= 0 or carry > 0:
total = carry
if i >= 0:
total += int(s1[i])
if j >= 0:
total += int(s2[j])
res.append(str(total % 10))
carry = total // 10
i -= 1
j -= 1
# remove leading zeroes which are currently
# at the back due to reversed string res
while res and res[-1] == '0':
res.pop()
# reverse our final string
return ''.join(reversed(res)) if res else "0"
# Function to find minimum sum using count array approach
def minSum(arr):
# Count array to store frequency of each digit
count = [0] * 10
# Count occurrences of each digit
for num in arr:
count[num] += 1
# Two strings for storing the two minimum numbers
s1 = []
s2 = []
# Flag to alternate between s1 and s2
firstNum = True
# Traverse count array from 0 to 9
for digit in range(10):
while count[digit] > 0:
if firstNum:
if not (len(s1) == 0 and digit == 0):
s1.append(str(digit))
firstNum = False
else:
if not (len(s2) == 0 and digit == 0):
s2.append(str(digit))
firstNum = True
count[digit] -= 1
# Handle case where s1 or s2 might be empty
if not s1:
s1.append("0")
if not s2:
s2.append("0")
return addString(''.join(s1), ''.join(s2))
if __name__ == "__main__":
arr = [6, 8, 4, 5, 2, 3, 0]
print(minSum(arr))
using System;
using System.Collections.Generic;
class GfG {
// Function to add two strings and return the result
static string addString(string s1, string s2) {
int i = s1.Length - 1;
int j = s2.Length - 1;
// initial carry is zero
int carry = 0;
// we will calculate and store the
// resultant sum in reverse order in res
List<char> res = new List<char>();
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry;
if (i >= 0)
sum += (s1[i] - '0');
if (j >= 0)
sum += (s2[j] - '0');
res.Add((char)(sum % 10 + '0'));
carry = sum / 10;
i--;
j--;
}
// remove leading zeroes which are currently
// at the back due to reversed string res
while (res.Count > 0 && res[res.Count - 1] == '0')
res.RemoveAt(res.Count - 1);
// reverse our final string
res.Reverse();
return res.Count == 0 ? "0" : new string(res.ToArray());
}
// Function to find minimum sum using count array approach
static string minSum(int[] arr) {
// Count array to store frequency of each digit
int[] count = new int[10];
// Count occurrences of each digit
foreach (int num in arr) {
count[num]++;
}
// Two strings for storing the two minimum numbers
string s1 = "";
string s2 = "";
// Flag to alternate between s1 and s2
bool firstNum = true;
// Traverse count array from 0 to 9
for (int digit = 0; digit < 10; digit++) {
// Add digit to appropriate string
// while it has occurrences
while (count[digit]-- > 0) {
if (firstNum) {
// Avoid leading zeros for both numbers
if (!(s1.Length == 0 && digit == 0))
s1 += digit.ToString();
firstNum = false;
} else {
if (!(s2.Length == 0 && digit == 0))
s2 += digit.ToString();
firstNum = true;
}
}
}
// Handle case where s1 or s2 might be empty
if (s1.Length == 0) s1 = "0";
if (s2.Length == 0) s2 = "0";
return addString(s1, s2);
}
static void Main() {
int[] arr = { 6, 8, 4, 5, 2, 3, 0 };
Console.WriteLine(minSum(arr));
}
}
// Function to add two strings and return the result
function addString(s1, s2) {
let i = s1.length - 1;
let j = s2.length - 1;
// initial carry is zero
let carry = 0;
// we will calculate and store the
// resultant sum in reverse order in res
let res = [];
while (i >= 0 || j >= 0 || carry > 0) {
let total = carry;
if (i >= 0) total += parseInt(s1[i]);
if (j >= 0) total += parseInt(s2[j]);
res.push(total % 10);
carry = Math.floor(total / 10);
i--;
j--;
}
// remove leading zeroes which are currently
// at the back due to reversed string res
while (res.length > 0 && res[res.length - 1] === 0) {
res.pop();
}
// reverse our final string
return res.reverse().join('') || "0";
}
// Function to find minimum sum using count array approach
function minSum(arr) {
// Count array to store frequency of each digit
let count = new Array(10).fill(0);
// Count occurrences of each digit
for (let num of arr) {
count[num]++;
}
// Two strings for storing the two minimum numbers
let s1 = [];
let s2 = [];
// Flag to alternate between s1 and s2
let firstNum = true;
// Traverse count array from 0 to 9
for (let digit = 0; digit < 10; digit++) {
while (count[digit]-- > 0) {
if (firstNum) {
if (!(s1.length === 0 && digit === 0))
s1.push(digit);
firstNum = false;
} else {
if (!(s2.length === 0 && digit === 0))
s2.push(digit);
firstNum = true;
}
}
}
// Handle case where s1 or s2 might be empty
if (s1.length === 0) s1.push(0);
if (s2.length === 0) s2.push(0);
return addString(s1.join(''), s2.join(''));
}
// Driver Code
let arr = [6, 8, 4, 5, 2, 3, 0];
console.log(minSum(arr));
Output
604