我有一个问题,我需要找到数组中两个不同元素之间的最大距离。
例如:给定数组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);
如何在时间复杂度方面做得更好?
答案 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)
时间复杂度。
修改:让我们证明至少有一个索引是0
或length - 1
。让我们通过矛盾来做。假设我们有一个像
a, b, c, .... d, e, f, g
^ ..... ^ <- solution indexes (no borders)
c
左侧的项目必须为d
,否则我们可以采用a
或b
个索引,并拥有改进的解决方案。 d
右侧的项目必须为c
,否则我们可以再次将最后一个索引推向右侧并获得更好的解决方案。所以我们有
d, d, c .... d, c, c, c
^ .... ^ <- solution indexes
现在,由于d <> c
(c..d
是解决方案),我们可以改进解决方案
d, d, c .... d, c, c, c
^ .... ^ <- solution indexes
^ .... ^ <- better solution
我们有一个矛盾(所谓的解决方案不是一个 - 我们有更好的选择),这就是为什么至少有一个索引必须是0
或length - 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!]
之间的最大差异可以是起始元素与i
或i
之间以及最后一个元素
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
不变并保持转轮循环相同。