两个不同数组的最大算术序列

时间:2019-10-20 17:15:24

标签: java arrays math sequence

给出两个整数数组a和b,尝试通过将b中的整数添加到a中来创建算术序列。如果不存在算术序列,则返回a或-1的最大长度。 a = [2,4,8],b = [1,6,10,12]-> a = [2,4,6,8,10,12]->返回6

我尝试创建一个新数组并合并a和b并计算最长的子序列,但是该计数可以从a中删除不应触摸的元素

static int maxSeq(int[] arr1, int[] arr2){
        if(arr1.length ==0)return 0;
        int n =arr1.length, m = arr2.length;
        int[] arr = new int[n+m];
        System.arraycopy(arr1,0,arr,0,n);
        System.arraycopy(arr2,0,arr,n,m);
        Arrays.sort(arr);
        int result =0;
        Map<Integer,Integer>[]d = new HashMap[n+m];
        for(int i =0; i < arr.length;i++){
            d[i] = new HashMap<Integer, Integer>();
        }
        for(int i =1; i < arr.length; ++i){
            for(int j = 0; j<i;++j ){
                int diff = arr[i]-arr[j];

                int len =2;

                if(d[j].containsKey(diff)){
                    len = d[j].get(diff) +1;
                }



                d[i].put(diff,len);

                result = Math.max(result,d[i].get(diff));


            }
        }
        return result;
    }

a = [2,4,8],b = [1,6,10,12]-> a = [2,4,6,8,10,12]->返回6      int [] a = {5,7,13,14},b = {9,11,15};返回-1而不是6

4 个答案:

答案 0 :(得分:0)

如果使用列表和子列表,这可能是最简单的。

   public static void main(String[] args) {

      // generate some test data for verification.  The list with the * is
      // the actual sequence which can be commented out if not wanted.
      Random r = new Random();
      int[][] testCases = IntStream.range(0, 20).mapToObj(
            a -> r.ints(r.nextInt(6) + 3, 0, 30).toArray()).toArray(
                  int[][]::new);


      for (int i = 0; i < testCases.length - 1; i++) {
         int[] a = testCases[i];
         int[] b = testCases[i + 1];
         System.out.println(Arrays.toString(a));
         System.out.println(Arrays.toString(b));
         System.out.println(maxseq(a, b));
         System.out.println("---------------------------");
      }
      // System.out.println(maxSeq(a, b));
   }
   }

   public static int maxseq(int[] a, int[] b) {

     // copy arrays to main list
      List<Integer> ab = new ArrayList<>();
      for (int i : a) {
         ab.add(i);
      }
      for (int i : b) {
         ab.add(i);
      }

      // sort list in ascending order
      Collections.sort(ab);

      // empty sublist
      List<Integer> subList = List.of();

      int start = 0;
      for (int i = 2; i < ab.size(); i++) {
         // get initial difference
         int d = ab.get(start + 1) - ab.get(start);
         if (ab.get(i) - ab.get(i - 1) == d) {
            // update sublist if difference is same
            subList = ab.subList(start, i + 1);
         }
         else {
            // else start anew.
            start = i - 1;
         }
      }
      // and return result
      System.out.println("*" + subList());
      return subList.size() > 2 ? subList.size()
            : -1;
   }

答案 1 :(得分:0)

我认为您应该尝试修复代码。

if(d[j].containsKey(diff)){ len = d[j].get(diff) +1; }

在这里,您正在某个索引j的映射中寻找differences,并且应该只有一个键值对映射,而不是映射数组。

答案 2 :(得分:0)

这里的关键是用数组B中的数字填充数组A,以便A成为算术序列。

解决方案:

  • 首先找到A中2个结果数之间的最小差距
  • 使用给定的“ gap”,尝试查看是否可以通过遍历2个数组来构建算术序列,并找出B中的数字是否可以填充数组A,以便A通过step =“ gap”成为算术。如果成功,请计算长度。
  • 如果可以找到它,请尝试遍历原始“间隙”的所有除数作为新的“间隙”,然后再测试一次,以查看较小的间隙是否可以构建更长的算术序列。 (示例:A = [1,5],B = [3,7,9] =>上一步,我们可以构建算术序列[1,5,9],但最终答案应为[1,3, 5,7,9]。

答案 3 :(得分:0)

我想分享我的解决方案(可能没有优化,我没有写很多测试,但它适用于您的两个示例测试):

想法:

  1. 注意等差数列的共差d的上限为min(a[i] - a[i-1]),否则我们将无法访问a中的所有元素
  2. 我们对共同差d进行迭代以检查每个潜在列表的长度,并找到最大长度

完整的 Python 代码:

(假设 a, b 都已排序)

def max_arithmetic_length(a, b):

    min_diff = float('inf')  # common difference d is upper bounded by min_diff

    for i in range(1, len(a)):
        min_diff = min(min_diff, a[i] - a[i-1])

    d_a = {x : True for x in a}
    d_b = {x : True for x in b}

    max_cnt = 0
    for d in range(1, min_diff + 1):

        skip_current_d = False  # a switch to skip outer loop
        for x in a:
            if (x - a[0]) % d != 0:  #  must exist: a[i] - a[0] = kd
                skip_current_d = True
                break

        if skip_current_d:
            continue

        cur = a[0]
        cnt = 0
        visited = {}
        while cur in d_a or cur in d_b:
            cnt += 1
            visited[cur] = True
            cur += d

        if a[-1] not in visited:  # if the last element in a is visited, then every element in a is visited
            continue

        # check those smaller than a[0] (may only exist in b)
        cur = a[0] - d
        while cur in b:
            cnt += 1
            cur -= d

        max_cnt = max(cnt, max_cnt)

    return max_cnt if max_cnt  else -1

a = [2, 4, 8]
b = [1, 6, 10, 12]
print(max_arithmetic_length(a,b))  # return  6

a = [5,7,13,14]
b = [9,11,15]
print(max_arithmetic_length(a,b))  # return -1