数组中两个不同元素之间的最大距离

时间:2018-02-21 08:00:10

标签: java arrays algorithm integer

我有一个问题,我需要找到数组中两个不同元素之间的最大距离。

例如:给定数组4,6,2,2,6,6,4,该方法应返回5作为最大距离。

我能够使用两个for循环来解决问题,但它不是一个优化的解决方案。我试图通过单个for循环来优化它。

这是我目前的解决方案:

int [] A = {4,6,2,2,6,6,4};
int N = A.length;
int result = 0;

for (int i = 0; i < N; i++){
    for (int j = i; j < N; j++) {
        if(A[i] != A[j]){
            result = Math.max(result, j - i);
        }
    }
}

// tried below code but it is not efficient
//      for (int i = 0; i < N; i++){
//          
//          if(A[N-1] != A[i]){
//              result = Math.max(result, N-1-i);
//          }
//      }

System.out.println(result);

如何在时间复杂度方面做得更好?

2 个答案:

答案 0 :(得分:7)

简单(不是嵌套)循环就足够了,但两种情况应该被用于 帐户:最好的结果是

  4,6,2,2,6,6,4
    ^         ^ - moving first

  4,6,2,2,6,6,4
  ^         ^   - moving last

例如:[4, 2, 4, 4, 4] 先移动会带来答案,如果[4, 4, 4, 2, 4] 最后移动应该使用。

  int first = 0;
  int last = A.length - 1;

  // 1st case: moving "first"
  while (first < last) {
    if (A[first] == A[last])
      first++;
    else
      break;
  }

  int diff1 = last - first;

  first = 0;
  last = A.length - 1;

  // 2nd case: moving "last"
  while (first < last) {
    if (A[first] == A[last])
      last--;
    else
      break;
  }

  int diff2 = last - first;

  // result is the max between two cases
  int result = diff1 > diff2
    ? diff1
    : diff2;

所以我们有O(N)时间复杂度。

修改:让我们证明至少有一个索引是0length - 1。让我们通过矛盾来做。假设我们有一个像

这样的解决方案
  a, b, c, .... d, e, f, g
        ^ ..... ^  <- solution indexes (no borders)

c左侧的项目必须为d,否则我们可以采用ab个索引,并拥有改进的解决方案。 d右侧的项目必须为c,否则我们可以再次将最后一个索引推向右侧并获得更好的解决方案。所以我们有

  d, d, c .... d, c, c, c
        ^ .... ^  <- solution indexes 

现在,由于d <> cc..d是解决方案),我们可以改进解决方案

  d, d, c .... d, c, c, c
        ^ .... ^           <- solution indexes 
  ^       ....          ^  <- better solution

我们有一个矛盾(所谓的解决方案不是一个 - 我们有更好的选择),这就是为什么至少有一个索引必须是0length - 1。< / p>

现在我们有 2 的情节来测试:

  a, b, ..... y, z
     ^  ......   ^ <- moving first
  ^  ......   ^    <- moving last

我们可以将两个条件合并到if并且只有一个循环:

  int result = 0;

  for (int i = 0; i < A.length; ++i)
    if (A[i] != A[A.length - 1] || A[0] != A[A.length - 1 - i]) {
      result = A.length - i - 1;

      break;
    }

答案 1 :(得分:3)

这可以在一个循环中完成

考虑一下。

索引var key = getSwiftArrayFromPlist()[indexPath.row]["firstname"] var value = getSwiftArrayFromPlist()[indexPath.row][key!] 之间的最大差异可以是起始元素与ii之间以及最后一个元素

i

我们能够实现int main() { vector<int> v {4, 6, 2, 2, 6, 6, 4}; int start = 0, end = v.size() -1; int result = 0; for(int i=0; i< v.size(); ++i) { if(v[i] != v[start]) { result = max(result, i); } if(v[i] != v[end]) { result = max(result, end - i); } } return result; } 算法的原因是因为

考虑O(N)

在索引v = [4, 4, 2, 3, 4, 4],我们检查是否可以找到最大可能距离,即最后一个元素,但由于它们是相同的,我们无法考虑它。

此数组的i = 0最大可能答案为5.

i = 0

[4, 4, 2, 3, 4, 4] ^ ,我们再次检查数组的两端是否仍然相同,以便我们继续前进。

真正的节省在这里,我们不必检查每一个其他条目 保持开始于i = 1

所以,在i = 0,我们发现可以用数组的末尾获得最大值

i = 2

与保持[4, 4, 2, 3, 4, 4] ^ ^ ^ start i end 不变并保持转轮循环相同。