zoukankan      html  css  js  c++  java
  • [LeetCode 625] Minimum Factorization

    Given a positive integer a, find the smallest positive integer b whose multiplication of each digit equals to a.

    If there is no answer or the answer is not fit in 32-bit signed integer, then return 0.

    Example 1: input 48, output 68

    Example 2: input 15, output 35

    Key Observation: 

    1. each digit of the output must be in range [2, 9] because 1 does not change the digits product but will make the output bigger.
    2. We should put bigger digits on lower significant digits.
    3. composite digits is preferred over non-composite digits. For example, if we can use 9 as a valid digit, then we would not choose two 3s.

    Based on the above observations, the algorithm is straightforward.
    1. from 9 to 2, greedily add valid digits until it is impossible to do so.
    2. after step 1, the input a is either 1 or > 1.

    2a. If > 1, then we know that a must have a prime factor that is bigger than 9. In this case, it is impossible to get a valid factorization, return 0.

    2b. if == 1, then either input a is 1 and we do not have any digits or input a is > 1 but reduced to 1 with some digits. Return 1 for the former case, for the latter case, check if the smallest 

    number formed by all digits fits in 32-bit signed integer, return this number if it does, 0 otherwise.

    class Solution {
        public int smallestFactorization(int a) {
            List<Integer> digits = new ArrayList<>();
            for(int i = 9; i >= 2; i--) {
                while(a % i == 0) {
                    digits.add(i);
                    a /= i;
                }
            }
            if(a > 1) {
                return 0;
            }
            else if(a == 1 && digits.size() == 0) {
                return 1;
            }
            long d = 0;
            for(int i = digits.size() - 1; i >= 0; i--) {
                d = d * 10 + digits.get(i);
            }
            return d > Integer.MAX_VALUE ? 0 : (int)d;
        }
    }

     

    The above solution is already optimal. However there is another more complicated way of sloving this problem. We'll go through it here as an exercise. 

    If the input is < 10, then the output is the input a itself. 

    If a >= 10,  if there is prime factor that is > 10, it is impossible to get a valid answer. In another word, we can only use prime factors 2,3,5,7 to get a valid answer. For 5 and 7, they must form their own digits. For 2 and 3, we can have the following combinations: 2 * 2 = 4, 2 * 2 * 2 = 8, 2 * 3 = 6, 3 * 3 = 9. How we should make an optimal combination is still not clear. 

    Base on this, we can apply the integer prime factorization algorithm to get all a's prime factors. Then we check if there is any multiple digits prime factor, if there is, return 0. Otherwise,

    we try to combine all prime factors from both directions. First from small to big, then from big to small. Then pick the smaller result and do a final check if it fits in 32-bit signed integer range.

     

    class Solution {
        public int smallestFactorization(int a) {        
            if(a < 10) {
                return a;
            }
            List<Integer> primeFactors = new ArrayList<>();
            while(a % 2 == 0) {
                primeFactors.add(2);
                a /= 2;
            }
            for(int i = 3; i <= Math.sqrt(a); i += 2) {
                while(a % i == 0) {
                    primeFactors.add(i);
                    a /= i;
                }
            }
            if(a > 2) {
                primeFactors.add(a);
            }
            if(primeFactors.size() < 2) {
                return 0;
            }
            int i = 0;
            long v1 = 0;
            List<Integer> ans1 = new ArrayList<>();
            while(i < primeFactors.size()) {
                if(primeFactors.get(i) > 10) {
                    v1 = (long)Integer.MAX_VALUE + 1;
                    break;
                }
                int d = primeFactors.get(i);
                while(i < primeFactors.size() - 1 && d * primeFactors.get(i + 1) < 10) {
                    d = d * primeFactors.get(i + 1);
                    i++;
                }
                ans1.add(d);
                i++;
            }
            if(v1 == 0) {
                Collections.sort(ans1);
                for(int j = 0; j < ans1.size(); j++) {
                    v1 = v1 * 10 + ans1.get(j);
                }            
            }
            
            i = primeFactors.size() - 1;
            long v2 = 0;
            List<Integer> ans2 = new ArrayList<>();
            while(i >= 0) {
                if(primeFactors.get(i) > 10) {
                    v2 = (long)Integer.MAX_VALUE + 1;
                    break;
                }
                int d = primeFactors.get(i);
                while(i > 0 && d * primeFactors.get(i - 1) < 10) {
                    d = d * primeFactors.get(i - 1);
                    i--;
                }
                ans2.add(d);
                i--;
            }
            if(v2 == 0) {
                Collections.sort(ans2);
                for(int j = 0; j < ans2.size(); j++) {
                    v2 = v2 * 10 + ans2.get(j);
                }              
            }
      
            long vMin =  Math.min(v1, v2);
            return vMin > Integer.MAX_VALUE ? 0 : (int)vMin;
        }
    }



  • 相关阅读:
    wdcp升级php和mysql
    centos安装中文支持(转)
    centos5.5用phpstudy一键安装配置虚拟主机后,yum配置代理服务器squid
    http status 汇总
    关于html标签元素的data-*属性
    [分 享] PHPCMS V9 更换域名,附件地址无法批更新(更换变便)问题>解决方法!!
    svn服务器配置小记
    Camstar Portal modeling user guid --设置本地时间
    msdn webcast 下载地址整理
    mvc 项目下 webservice 程序无法运行
  • 原文地址:https://www.cnblogs.com/lz87/p/13277180.html
Copyright © 2011-2022 走看看