【问题标题】:Find the number that can be divided from a array of numbers找到可以从数字数组中除的数字
【发布时间】:2022-11-10 22:37:48
【问题描述】:

找到最小的数 M,将其除以输入数组中的 n-1 个数。如果没有这样的 M 则返回 -1。

例子:

array = [2,3,5]

回答 :

6

解释 :

6 can be divided by 2 and 3

例子:

array = [2,3,6]

回答:

 -1

解释 :

It's not possible in this case so return -1.

我的代码:

由于我们需要找到最小的M,所以我只选择从 0 到 n-2 的元素

public int process(int[] arr) {
    int answer = 1;
    for(int i=0; i<arr.length-1; i++) {
        answer *= arr[i];
    }
    return answer;
}

该程序适用于这 2 个示例测试用例,但对于多个隐藏的测试用例却失败了。我试图了解我在这里缺少什么。

【问题讨论】:

  • 您正在将给定数组中除最后一个元素之外的所有元素按给定顺序相乘。如果您拥有的示例数组通过[5, 3, 2] 怎么办?如果给你[2, 3, 5, 6]怎么办?
  • 为什么 [2,3,6] 的结果是 -1 而不是 6? 6 可以除以 2 和 3(如第一个示例)||您声明“该程序适用于这两个示例测试用例”,但第二个示例没有返回 -1 ??
  • @user16320675 必须能被 n - 1 整除,6 也能被 6 整除
  • 我明白了,就像“只能被 n-1 个值整除,也就是说,不能被一个且只能被其中一个数字整除”——但在这种情况下,发布的代码不会返回 -1

标签: java algorithm


【解决方案1】:

计算下公倍数

任务中的一个问题是计算 2 个数字的下公倍数。方法public int lowerCommonMultiple(int x1, int x2) 解决了这个问题,我认为它可以在其他情况下使用。

类方法列表

所有代码都包含在BestMultiple 类的方法中。这些方法(不包括main)是:

  • public int[] removeElem(int[] tensArray, int rm_index):用于从数组中移除一个元素
  • public int lowerCommonMultiple(int x1, int x2):计算 2 个数的下公倍数
  • private int getLowerCommonMultipleNnumber(int[] arr):计算数组中包含的 N-1 个整数的下公倍数
  • public int process(int[] arr):计算N个整数数组的恰好N-1个数的下倍数;它管理许多测试奇怪的情况(数组为空、elem<=0 等)

可能是代码没有优化,但我希望它是正确的(添加的输出表明它可以正常工作,至少在选择的测试用例的情况下)。

public class BestMultiple {

    /*++++++++++++++++++++++++++++++++++++++++++++
      Method: removeElem() remove an element from
              an array.
     +++++++++++++++++++++++++++++++++++++++++++*/
    public int[] removeElem(int[] tensArray, int rm_index) {
        // Create a proxy array of size one less than original array
        int[] proxyArray = new int[tensArray.length - 1];
        // copy all the elements in the original to proxy array
        // except the one at index
        for (int i = 0, k = 0; i < tensArray.length; i++) {
            // check if index is crossed, continue without copying
            if (i == rm_index) {
                continue;
            }
            // else copy the element
            proxyArray[k++] = tensArray[i];
        }

        return proxyArray;
    }

    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      Method: lowerCommonMultiple() Calculates the Lower Common
              multiple for 2 numbers
     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    public int lowerCommonMultiple(int x1, int x2) {
        int lcm = 1;
        int max = x1;
        if ((x1 == 0) || (x2 == 0)) {
            lcm = 0;
        } else {
            if (x2 > x1) {
                max = x2;
            }
            for (int i = 2; i <= max; i++) {
                int exp_x1 = 0;
                int exp_x2 = 0;
                int exp = 0;
                if (x1 > 1) {
                    while ((x1 % i) == 0) {
                        exp_x1++;
                        x1 /= i;
                    }
                }
                if (x2 > 1) {
                    while ((x2 % i) == 0) {
                        exp_x2++;
                        x2 /= i;
                    }
                }
                if ((exp_x1 > 0) || (exp_x2 > 0)) {
                    exp = exp_x1;
                    if (exp_x2 > exp) {
                        exp = exp_x2;
                    }
                    while (exp > 0) {
                        lcm *= i;
                        exp--;
                    }
                }
            }
        }
        return lcm;
    }
    
    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Method: process() Calculates the lower common  multiple of N-1
            integer contain in an array
   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    private int getLowerCommonMultipleNnumber(int[] arr) {
        int multiple = 1;
        if (arr.length >= 2) {
            multiple = lowerCommonMultiple(arr[0], arr[1]);
            for (int j = 2; j < arr.length; j++) {
                multiple = lowerCommonMultiple(multiple, arr[j]);
            }
        } else {
            // array with only 2 elements
            multiple = arr[0];
        }
        return multiple;
    }

    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      Method: process() Calculates the lower multiple of exactly N-1
      number of an array of N integer
     +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    public int process(int[] arr) {
        int answer;

        if (arr.length <= 1) {
            // array contains only one element or is empty => return -1
            answer = -1;
        } else {
            int pos_elem_zero = -1;
            int prod = 1;
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] > 0) {
                    prod *= arr[i];
                } else {
                    if (arr[i] < 0) {
                        // integer < 0 are not allowed
                        return -1;
                    }
                    if (pos_elem_zero == -1) {
                        pos_elem_zero = i;
                    } else {
                        // there are more element == 0
                        return -1;
                    }
                }
            }
            if (pos_elem_zero >= 0) {
                // there is one element == 0 
                arr = this.removeElem(arr, pos_elem_zero);
                return getLowerCommonMultipleNnumber(arr);
            }

            // managing of normal test case
            answer = prod;
            for (int i = 0; i < arr.length; i++) {
                int elem = arr[i];
                int[] arr2 = this.removeElem(arr, i);
                int multiple = getLowerCommonMultipleNnumber(arr2);
                if (multiple > elem) {
                    if ((multiple % elem) != 0) {
                        if (multiple < answer) {
                            answer = multiple;
                        }
                    }
                } else {
                    if (multiple < elem) {
                        answer = multiple;
                    }
                }
            }
            if (answer == prod) {
                answer = -1;
            }
        }
        return answer;
    }

    /*++++++++++++++++++++++++++++++++++++++++++
      Method: main() Executes test of process()
              method
     +++++++++++++++++++++++++++++++++++++++++*/
    public static void main(String[] args) {
        BestMultiple bm = new BestMultiple();
        int[] arr1 = {6,30,5,3};
        int[] arr2 = {1,2,3};
        int[] arr3 = {1,2,3,3};
        int[] arr4 = {6,7,5,3};
        int[] arr5 = {9,14, 21};
        int[] arr6 = {2,4};
        int[] arr7 = {2,3,5};
        int[] arr8 = {2,3,6};
        int[] arr9 = {2};
        int[] arr10 = {};
        int[] arr11 = {2,3,0};
        int[] arr12 = {0,2,3,0};
        int[] arr13 = {20,3};
        int[] arr14 = {0,6,15};
        int[] arr15 = {1,6,15,-1};
        int[] arr16 = {1,6,15};
        int[] arr17 = {2,3,0,6,15};        

        System.out.println("{6,30,5,3} --> " + bm.process(arr1));
        System.out.println("{1,2,3} --> " + bm.process(arr2));
        System.out.println("{1,2,3,3} --> " + bm.process(arr3));
        System.out.println("{6,7,5,3} --> " + bm.process(arr4));
        System.out.println("{9,14,21} --> " + bm.process(arr5));
        System.out.println("{2,4} --> " + bm.process(arr6));
        System.out.println("{2,3,5} --> " + bm.process(arr7));
        System.out.println("{2,3,6} --> " + bm.process(arr8));
        System.out.println("{2} --> " + bm.process(arr9));
        System.out.println("{} --> " + bm.process(arr10));
        System.out.println("{2,3,0} --> " + bm.process(arr11));
        System.out.println("{0,2,3,0} --> " + bm.process(arr12));
        System.out.println("{20,3} --> " + bm.process(arr13));
        System.out.println("{0,6,15} --> " + bm.process(arr14));
        System.out.println("{1,6,15,-1} --> " + bm.process(arr15));
        System.out.println("{1,6,15} --> " + bm.process(arr16));
        System.out.println("{2,3,0,6,15} --> " + bm.process(arr17));
    }
}

程序的输出

选择了测试用例的程序的输出是:

{6,30,5,3} --> -1
{1,2,3} --> 2
{1,2,3,3} --> 3
{6,7,5,3} --> 30
{9,14,21} --> 42
{2,4} --> 2
{2,3,5} --> 6
{2,3,6} --> -1
{2} --> -1
{} --> -1
{2,3,0} --> 6
{0,2,3,0} --> -1
{20,3} --> 3
{0,6,15} --> 30
{1,6,15,-1} --> -1
{1,6,15} --> 6
{2,3,0,6,15} --> 30

【讨论】:

  • 不确定这是否有效。假设你有[2, 3, 5, 6] 我相信你的代码会返回-1 但是我不明白为什么6 不会是这里的答案
  • @frankfalse 你是对的,我的错。但是您的解决方案仍然不正确
  • 反例:[9, 14, 21]。三个可能的答案是9*14=1269*21=18914*21=294。您的代码将生成 126,然后返回 -1,因为 126 可以被 21 整除。实际答案是 189,因为它不能被 14 整除。
  • 在您自己的示例中,[6, 7, 5, 3] 90 不正确。 30 更小,可被 3、5 和 6 整除,但不能被 7 整除
  • @用户3386109 42!还有什么
【解决方案2】:

您实现process() 的方式假定输入数组已排序。但无论如何,我认为排序在这里没有帮助。请注意,满足给定条件的数字可以除以最大的数字。对于[2, 3, 5, 6],它是6。将所有元素的乘积除以从最大到最小的连续元素并在第一个不是除数的地方停止也是不正确的。在示例[2, 4, 5, 6] 中,当正确答案为20 时,这将给出2 * 4 * 5 = 40

我的想法是使用受Sieve of Eratosthenes 启发的算法。注意满足条件的数不能大于所有元素的乘积。因此,创建一个表divisors[],其索引从0 到array 的元素的乘积,其中divisors[i] 表示array 中有多少元素除以i。遍历array 的元素并递增divisors[i] 中的所有元素,其中i 除以元素。然后找到divisors[i] == n - 1 对应的第一个i

限制是divisors 可以很大,这取决于array 的乘积,因此适用性将仅限于array 中相对较小的值。

【讨论】:

    【解决方案3】:

    您首先编写一个方法process,它计算每个子数组的最小数量,其中一个元素被排除在外:

    public static int process(int... arr) {
        int min = -1;
        for (int i = 0; i < arr.length; ++i) {
            int r = process(arr, i);
            if (r != -1) {
                if (min == -1) {
                    min = r;
                } else {
                    min = Math.min(min, r);
                }
            }
        }
        return min;
    }
    

    第二个process 方法如下所示:

    private static int process(int[] arr, int exclude) {
        int result = 0;
        for (int i = 0; i < arr.length; ++i) {
            if (i != exclude) {
                if (result == 0) {
                    result = arr[i];
                } else {
                    result = lcm(result, arr[i]);
                }
            }
        }
        if (result%arr[exclude] == 0) {
            return -1;
        }
        return result;
    }
    

    您需要一种计算两个数字的 LCM 的方法。在这里,我将使用第二种计算 GCD 的方法:

    private static int lcm(int a, int b) {
        return a*b/gcd(a,b);
    }
    
    
    private static int gcd(int a, int b) {
        if (a == 0) {
            return b;
        } else if (b == 0) {
            return a;
        } else {
            while (a != b) {
                if (a > b) {
                    a -= b;
                } else {
                    b -= a;
                }
            }
            return a;
        }
    }
    

    例子:

        System.out.println(process(2, 3, 5)); // prints 6
        System.out.println(process(2, 3, 6)); // prints -1
        System.out.println(process(9, 14, 21)); // prints 42 (divisible by 14 and 21, but not by 9
        System.out.println(process(6, 7, 5, 3)); // prints 30 (divisible by 6, 5, 3, but not by 7
    

    【讨论】:

      猜你喜欢
      • 2022-10-04
      • 2016-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 2021-01-02
      相关资源
      最近更新 更多