【问题标题】:LCM of all the numbers in an array in JavaJava中数组中所有数字的LCM
【发布时间】:2013-07-17 01:16:20
【问题描述】:

我有一个整数数组,我试图找到数组中所有值的 LCM(最小公倍数)。我已经单独写了一个lcm 方法;它需要两个值作为输入,并返回 lcm。我的 lcm 方法工作得很好,但是当我用它来查找所有值的 LCM 时,我得到了错误的答案。

这是我的gcdlcm 方法:

public static int gcd(int a, int b){
    if (a<b) return gcd(b,a);
    if (a%b==0) return b;
    else return gcd(a, a%b);
}


public static int lcm(int a, int b){
    return ((a*b)/gcd(a,b));

} 

这就是我对数组值的 lcm 所拥有的:

public static int lcmofarray(int[] arr, int start, int end){
    if ((end-start)==1) return lcm(arr[start],arr[end-1]);
    else return (lcm (arr[start], lcmofarray(arr, start+1, end)));
}

当我输入一个数组,其中数字 1 到 5 为 arr,0 为 start,数组长度为 end,我得到 30 作为答案,而我想要 60。当我输入了一个包含从 1 到 10 的所有数字的数组,我得到的是 840 而不是 2520。我真的无法解释。

算法应该可以工作——我已经在脑海中解决了。无法弄清楚我的代码有什么问题。

我们将不胜感激。

【问题讨论】:

  • 这里不要使用递归,只需遍历数组查找连续的 LCM。
  • 我不确定我是否理解您的设置方式,但您的第一个 if 语句是否会在同一个号码上调用 LCM 函数。例如,如果 start = 0,end = 1,那么您将返回 lcm(arr[0], arr[0]) = arr[0]
  • 我想我可以改用循环,但此时我想知道为什么我的代码不起作用。 @Kon我希望基本情况是:当数组中剩下两个元素时,找到两个元素的lcm。 (输入数组的元素永远不会少于两个。)我应该将其更改为 (end-start==2) 吗?
  • 您的代码实际上对我有用,并产生了预期的结果。 ideone.com/Afk4pO
  • 问题已经清楚了:else return gcd(b, a%b);

标签: java arrays recursion lcm


【解决方案1】:

如果您将 gcd 函数更改为

public static int gcd(int a, int b){
    if (a<b) return gcd(b,a);
    if (a%b==0) return b;
    else return gcd(b, a%b);
}

应该没问题。

【讨论】:

    【解决方案2】:

    这是使用公式 lcmgcd=ab

    为 n 个数字的数组查找 lcm 和 gcd 的程序
    public class Main
    {
        public static void main(String[] args) {
            int a[]={63,105,210};
            int lcm=1,fir=lcm,res=0;
            for(int i=0;i<a.length;i++)
            {
                int sec=a[i];
                lcm=(fir*sec)/gcd(fir,sec);
                fir=lcm;
            }
            for(int j=0;j<a.length;j++)
            {
                res=gcd(res,a[j]);
            }
            System.out.println("lcm is "+lcm+" "+"gcd is "+res);
        }
        
        public static int gcd(int a,int b)
        {
            if(b==0)
            {
                return a;
            }
            return gcd(b,a%b);
        }
    }
    

    【讨论】:

      【解决方案3】:

      上面的方法看起来不错,但是由于递归调用而导致堆栈溢出错误:

      请找到以下解决方案:

          public int findHCF(int a, int b) {
      
          if (b>a){
              return findHCF(b, a);
          }
      
          while(a%b!=0){
      
              int temp = b;
              b=a%b;
              a=temp;
          }
          return b;
      }
      

      【讨论】:

      • 我很确定,您也在进行递归调用。您能否强调一下,您的代码有何不同?
      • 不,我没有进行递归调用。我正在使用迭代方法。只有第一条语句 if(a
      • 我明白了。但是,我不明白交换ab 值的逻辑。顺便说一句,它给出了错误的输出。 ideone.com/aLKxuL
      • 是的,我查过了。不需要交换 a 和 b。但无论如何,它每次都会给我正确的输出。您能否提及输出不正确的用例?此外,请随时添加您的解决方案或修改我的解决方案。谢谢
      • 我在上一条评论中分享了一个链接。您的代码给出了错误的输出。如果我要更改您的代码,那么答案将完全改变:-)
      【解决方案4】:

      关于代码背后的逻辑的简要想法-

      LCM(a,b)=a*b/HCF(a,b)

      您可以使用以下代码执行此操作-

      package hackerrank;
      
      /*
       * Author Hirak JD
       */
      import java.util.Arrays;
      
      public class LCM {
          public static void main(String args[]) {
              int[] set= {2,3,6,8};
              int lcm=1;
              for(int each:set) {
                  lcm=calculateLcm(lcm,each);
              }
      
              System.out.println("LCM for "+Arrays.toString(set)+" is : "+lcm);
      
          }
      
          private static int calculateLcm(int lcm, int each) {
              return lcm*each/gcd(lcm,each);
          }
      
          private static int gcd(int val1, int val2) {
              if(val1==0||val2==0)
                  return 0;
      
              if(val1==val2)
                  return val1;
      
              if(val1>val2)
                  return gcd(val1-val2,val2);
              return gcd(val1,val2-val1);
          }
      }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        • 2012-03-22
        相关资源
        最近更新 更多