Java程序:查找数组中给定索引范围内的最大公约数(GCD)


在数据结构领域,范围查询是一种预处理方法,可以有效地对某些输入数据进行操作。范围查询负责回答对任何数据子集上的特定输入的任何查询。如果我们想从表中复制一些数据列,我们需要为该特定数据集维护一个索引。索引是一个直接链接或键,旨在提供对数据集的高效搜索过程。它主要用于加快从丢失的数据源中检索数据。

在数学中,最大公约数(GCD)是可以整除作为输入的两个整数的最大整数。这里,所有数字都必须具有非零值。举个例子:

GCD of 70, 80 = 10 (10 is the largest number which divides them with remainder as 0)
GCD of 42, 120, 285 = 3 (3 is the largest number which divides them with remainder as 0)

查找数组中给定索引范围内的最大公约数的算法(详细)

  • 步骤1 - 开始

  • 步骤2 - 构造arr[0]到arr[n-1]的部分

  • 步骤3 - 继续等分

  • 步骤4 - 对这两个部分进行递归调用

  • 步骤5 - 对于每个部分,只保存最大公约数的值到线段树中

  • 步骤6 - 构造另一个线段树,从下往上填充

  • 步骤7 - 每个节点存储一定范围内的GCD数据

  • 步骤8 - 如果节点范围是startQuery和endQuery,则返回节点值

  • 步骤9 - 否则,如果范围无效,则返回null或-1作为输出

  • 步骤10 - 否则,返回GCD函数作为递归调用

  • 步骤11 - 结束

查找数组中给定索引范围内的最大公约数的算法(简短)

  • 步骤1 - 假设a和b是两个非零整数

  • 步骤2 - 令a mod b = R

  • 步骤3 - 如果a=b且b=R

  • 步骤4 - 则重复步骤2和步骤3

  • 步骤5 - 直到a mod b大于零

  • 步骤6 - GCD = b

  • 步骤7 - 结束

查找数组中给定索引范围内的最大公约数的语法

Begin
   if c = 0 OR d = 0, then
      return 0
   if c = d, then
      return b
   if c > d, then
      return findGCD(c-d, d)
   else
      return findGCD(c, d-c)
End

在此语法中,我们可以看到可能的逻辑代码,如何找到两个非零数字的最大公约数。该过程的时间复杂度为O(Q*N*log(Ai)),辅助空间评估为O(1)。

方法

  • 方法 - 使用线段树查找给定范围内数字的GCD的程序

使用线段树查找给定范围内数字的GCD的程序

为了使用线段树查找给定范围内数字的GCD,我们需要遵循一些不可避免的步骤。

  • 线段树的构造

    • 输入数组的元素是叶节点。

    • 每个内部节点代表所有叶节点的GCD。

    • 可以使用线段树进行数组表示。

    • -2*(i+1),索引的左元素

      -2*(i+2),索引的右元素

      -父节点是floor((i-1)/2)

  • 使用给定数组构造新的线段树

    • 从段arr[0 . . . n-1]开始。

    • 将它们分成两半。

    • 对这两半都进行相同的调用。

    • 存储GCD的值。

  • 构造给定范围的GCD

    • 对于每个可能的查询,移动树的左右两半。

    • 当给定范围与一半重叠时;它返回节点。

    • 当它位于给定范围之外时,此时返回0。

    • 对于部分重叠,根据所遵循的方法遍历并获取返回。

示例

import java.io.*;
public class tutorialspointGCD{
   private static int[] segTree;
   public static int[] buildSegmentTree(int[] arr){
      int height = (int)Math.ceil(Math.log(arr.length)/Math.log(2));
      int size = 2*(int)Math.pow(2, height)-1;
      segTree = new int[size];
      SegementTree(arr, 0, arr.length-1, 0);
      return segTree;
   }
   public static int SegementTree(int[] arr, int startNode,int endNode, int si){
        if (startNode==endNode) {
            segTree[si] = arr[startNode];
            return segTree[si];
         }
         int mid = startNode+(endNode-startNode)/2;
        segTree[si] = gcd(SegementTree(arr, startNode, mid, si*2+1),
                          SegementTree(arr, mid+1, endNode, si*2+2));
        return segTree[si];
   }
   private static int gcd(int a, int b){
      if (a < b){
            int temp = b;
            b = a;
            a = temp;
         }
         if (b==0)
            return a;
        return gcd(b,a%b);
   }
   public static int findRangeGcd(int startNode, int endNode, int[] arr){
      int n = arr.length;
      if (startNode<0 || endNode > n-1 || startNode>endNode)
         throw new IllegalArgumentException("Invalid arguments");
      return findGcd(0, n-1, startNode, endNode, 0);
   }
   public static int findGcd(int startNode, int endNode, int startQuery, int endQuery, int si){
      if (startNode>endQuery || endNode < startQuery)
            return 0;
      if (startQuery<=startNode && endQuery>=endNode)
            return segTree[si];
      int mid = startNode+(endNode-startNode)/2;
      return gcd(findGcd(startNode, mid, startQuery, endQuery, si*2+1),
                   findGcd(mid+1, endNode, startQuery, endQuery, si*2+2));
   }
   public static void main(String[] args)throws IOException{
      int[] a = {10, 5, 18, 9, 24};
      buildSegmentTree(a);
      int l = 0, r = 1;
      System.out.println("Greatest Common Divisor is here. Please collect the data: "+findRangeGcd(l, r, a));
      l = 2;
      r = 4;
      System.out.println("Greatest Common Divisor is here. Please collect the data: "+findRangeGcd(l, r, a));
      l = 0;
      r = 3;
      System.out.println("Greatest Common Divisor is here s . Please collect the data: "+findRangeGcd(l, r, a));
   }
}

输出

Greatest Common Divisor is here. Please collect the data: 5
Greatest Common Divisor is here. Please collect the data: 3
Greatest Common Divisor is here s . Please collect the data: 1

结论

在今天的文章中,我们使用特定的编程环境开发了一些可能的代码。通过这些编码的逻辑和提到的算法,我们学习了如何正确地找到数组中给定索引范围内的最大公约数。

更新于:2023年4月6日

201 次浏览

开启您的职业生涯

完成课程获得认证

开始
广告