搜索
首页Java查找给定数组的 GCD 对

查找给定数组的 GCD 对

Feb 22, 2024 pm 12:37 PM
最大公约数排列

Java问答:查找给定数组的GCD对是一个常见问题,需要对数组中的数字进行最大公约数(GCD)的计算。在Java中,可以使用欧几里得算法来解决这个问题。在本篇文章中,php小编西瓜将介绍如何使用Java编写一个方法来查找给定数组的GCD对,帮助读者更好地理解和应用这一算法。

问题内容

给定一个大小为 n 的整数数组,其中 n 是偶数。从数组中选取 2 个数字并找到 gcd。同样,从数组中剩余的项中选取 2 项并找到 gcd。重复上述步骤找到 gcd 对。对 gcd 值求和并得到最高的总和。

约束:

n is in range 2 to 20
arr[i] is in range 1 to 10^9

示例 1:

arr = [3,4,9,5]

答案:

4

说明:

a) gcd of (4,5) is 1
b) gcd of (3,9) is 3
sum = 1+3 = 4. this is the highest possible gcd sum.

示例 2:

arr = [1,2,3,4,5,6]

答案:

6

说明:

a) gcd of (1,5) is 1
b) gcd of (2,4) is 2
c) gcd of (3,6) is 3
sum = 1+2+3 = 6. this is the highest possible gcd sum.

这是我的代码:

public static int solve(int[] ar) {
   int n = ar.length;
   Arrays.sort(ar);
   int sum = 0;
   for(int i=0; i<n/2; i++) {
     int a = ar.get(i), b = ar.get(n-i-1);
     int c = gcd(a,b); 
     sum += c;
   }
   return sum;
}

static int gcd(int a, int b)
{
    // if b=0, a is the GCD
    if (b == 0)
        return a;

    // call the gcd() method recursively by
    // replacing a with b and b with
    // modulus(a,b) as long as b != 0
    else
        return gcd(b, a % b);
}

我的代码适用于第一个示例,但为第二个示例提供了错误的输出。 我调试了一下,发现我使用的方法不正确。解决这个问题的正确方法是什么?

解决方法

我们可以递归搜索所有可能的方法来计算总 gcd。怎么办?

如果数组只包含两个元素,我们可以只返回这两个元素的 gcd。

如果它包含更多,让我们迭代所有值对。对于每一对,我们计算它的 gcd,并且我们还使用删除了两个值的数组副本递归调用我们的函数。如果我们将两个计算的结果相加,我们就会得到当前选择的值对的总 gcd。

现在我们只跟踪迄今为止找到的最佳 gcd,并在最后返回它。

这是(应该)完全做到这一点的代码。

int solve(int[] ar) {
  // if we have only two elements, there's not much else we can do.
  if(ar.length == 2) {
    return gcd(ar[0], ar[1]);
  }

  //keep track of the largest gcd
  int best = 0;
  
  // for every pair of values in the array
  //  make a copy of the array without the pair and call recursively
  for(int i = 0; i < ar.length; i++) {
    for(int j = i + 1; j < ar.length; j++) {
      
      int score = gcd(ar[i], ar[j]);
      
      // make a copy
      int[] ar2 = new int[ar.length - 2];
      int copy_k = 0;
      for(int k=0; k < ar.length; k++) {
        // skip values that we already visited
        if(k == i || k == j) {
          continue;
        }
        
        ar2[copy_k] = ar[k];
        copy_k += 1;
      }
      
      // call recursively
      score += solve(ar2);
      
      if(score > best) // we found a better pair
        best = score;
    }
  }
  
  return best;
}

这个算法相当慢。如果您需要加快速度,至少有两个方面可以改进:

  • 计算 gcd 是一项昂贵的操作。 预先计算所有可能的唯一值对的 gcd 并将它们存储在哈希图中将消除双重计算。
  • 它会多次检查一些可能的排列。 (例如,在下一次递归中选择第一对,然后选择第二对与选择第二对,然后选择第一对相同)我对如何解决这个问题有一些模糊的想法,但今天晚上太晚了,抱歉。

很可能存在更快的算法,这只是我的想法。

编辑:好吧,经过一番睡眠后,我突然明白了。如果我们在创建对时省略外循环,我们将不会得到任何重复的对排序。基本上只是在各处用 0 替换 i ,如下所示:

for(int j = 1; j < ar.length; j++) {
    
  int score = gcd(ar[0], ar[j]);
  
  // Make a copy
  int[] ar2 = new int[ar.length - 2];
  int copy_k = 0;
  for(int k=1; k < ar.length; k++) {
    // Skip values that we already visited
    if(k == j) {
      continue;
    }
    
    ar2[copy_k] = ar[k];
    copy_k += 1;
  }
}

以上是查找给定数组的 GCD 对的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:stackoverflow。如有侵权,请联系admin@php.cn删除

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前By尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器