Tuesday, August 2, 2011

Generate Max Number from an Integer Array



Question:
You are given a list of positive int numbers, find out the max number that can be comprised of these input int numbers.

Example:
For input 1, 2, 3, the max number would be 321.
For 8, 87, 896, the max number would be 896887.

Answer:
For example, if the numbers are 24, 243, 2435? The max number should be [2435][243][24].
Is there a way we can sort this array, and get a new array: [2435, 243, 24]?

When we sort this array, we can define a comparator. When it compares two numbers (say a and b), if the two numbers has same digit numbers, we directly compare it, if they have different digit numbers (say a has less digit numbers than b), for the number (a in this case) has less digit numbers, we would get a new int number (get a new int a0 from b) by right padding it with the original digit numbers, and get a new number a0, then compare a0 and b.

So when compare 24 and 2435, we would think we are actually comparing 2[424] and 2435, so in the descending sorted array, 2535 would come before 24.

So the descending sorted array would be [2435, 243, 24], as 2435 > 243[2] > 24[24]; the generated max number would be [2435][243][24], this would be exactly what we expect.

Code:
The complete algorithm/test code and also many other algorithm problems and solutions are available from https://github.com/programmer-plus.
package org.codeexample.maxNumber;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.codeexample.common.OverflowException;
import org.codeexample.common.Utils;
class MyComparator implements Comparator<Integer> {
	/**
	 * For input 87 and 8, it would return -1, for 89 and 8, return 1, for 88
	 * and 8, return 0.
	 */
	public int compare(Integer int1, Integer int2) {
		if (int1 == null)
			return -1;
		if (int2 == null)
			return 1;
		// if eqauls, return directly to improve efficiency.
		if (int1.equals(int2))
			return 0;
		int int1DigitNumber = Utils.getNumberOfDigits(int1), int2DigitNumber = Utils
				.getNumberOfDigits(int2);
		if (int1DigitNumber > int2DigitNumber) {
			int2 = rightPadNumber(int2, int1DigitNumber);
		} else if (int1DigitNumber < int2DigitNumber) {
			int1 = rightPadNumber(int1, int2DigitNumber);
		}
		return int1.compareTo(int2);
	}
	/**
	 * @param ia
	 * @param newDigitalNumber
	 * @return pad the number by the original digital numbers in order. <br>
	 *         For example, for input 98, 5, it would return 98989 - five
	 *         numbers.
	 * @throws IllegalArgumentException,
	 *             if the new digital number is less than the digital number of
	 *             the old integer.
	 * @throws OverflowException,
	 *             if the generated number would be larger than
	 *             Integer.MAX_VALUE
	 */
	public static int rightPadNumber(int ia,
			int newDigitalNumber)
			throws IllegalArgumentException,
			OverflowException {
		int oldNumbers = Utils.getNumberOfDigits(ia);
		if (oldNumbers > newDigitalNumber) {
			throw new IllegalArgumentException(
					"Invalid parameters: "
							+ ia
							+ " has "
							+ oldNumbers
							+ " digits, its larger than the specified new digit number: "
							+ newDigitalNumber);
		} else if (oldNumbers == newDigitalNumber) {
			return ia; // Improve efficiency.
		}
		// example: to pad 98 to five numbers: 98988.
		boolean negative = ia < 0;
		if (negative) {
			ia = -ia;
		}
		String orginalString = String.valueOf(ia);
		StringBuffer resultString = new StringBuffer(
				orginalString);
		int diff = newDigitalNumber - oldNumbers;
		while (diff >= oldNumbers) {
			resultString.append(orginalString);
			diff -= oldNumbers;
		}
		// now, result = 9898, diff = 1;
		if (diff > 0) {
			resultString.append(orginalString.substring(0,
					diff));
		}
		if (negative) {
			resultString.insert(0, "-");
		}
		try {
			return Integer.valueOf(resultString.toString());
		} catch (NumberFormatException e) {
			throw new OverflowException(e);
		}
	}
}
public class MaxNumber {
	/**
	 * @see org.codeexample.maxNumber#maxNumber(java.util.List)
	 */
	public static int maxNumber(int[] ia)
			throws IllegalArgumentException,
			OverflowException {
		return maxNumber(Utils.toList(ia));
	}
	/**
	 * @param la,
	 *            a list of positive Integer numbers
	 * @return the max value that is generated by concatting each Integer value<br>
	 *         For example, for input 8, 87, 89, it would return 89887
	 * @throws IllegalArgumentException,
	 *             if the parameters include negative number
	 * @throws OverflowException,
	 *             if the generated number would be larger than
	 *             Integer.MAX_VALUE
	 */
	public static int maxNumber(List<Integer> la)
			throws IllegalArgumentException,
			OverflowException {
		Collections.sort(la, new MyComparator());
		Collections.reverse(la);
		Iterator<Integer> iterator = la.iterator();
		int result = 0;
		while (iterator.hasNext()) {
			int tmpi = iterator.next();
			if (tmpi < 0) {
				throw new IllegalArgumentException(
						"The list contains negative number: "
								+ tmpi);
			}
			int digitNumber = Utils.getNumberOfDigits(tmpi);
			// result = (10^digitNumber)*result + tmpi;
			result = Utils.safeMultiply(new Double(Math
					.pow(10, digitNumber)).intValue(),
					result);
			result = Utils.safeAdd(result, tmpi);
		}
		return result;
	}
}

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts