我正在尝试解决Sherlock和Array算法任务。我有数组,我需要在数组中找到元素,使得左侧元素的总和等于它的右侧元素,就像我在标题中提到的那样。我的算法适用于小型阵列,但对于大型阵列来说,它太懒散了,我该怎么做才能提高它的速度?
提一下。该算法不接受大小为1和2的数组。
public static boolean isSherlock(int arr[])
{
int length = arr.length;
int leftSum = 0;
int rightSum = 0;
for(int i=0; i<length-1; i++)
{
leftSum = 0;
rightSum = 0;
// Left sum for index i
for(int j=0; j<i; j++)
leftSum+=arr[j];
// Right sum for index i
for(int j=i+1; j<length && leftSum != 0; j++)
rightSum+=arr[j];
if(leftSum == rightSum && leftSum != 0 && rightSum != 0)
{
return true;
}
}
return false;
}
这是O(N ^ 2)有没有办法在O(n)中做到这一点?
答案 0 :(得分:3)
线性解决方案非常简单。
计算数组 A 中所有元素的总和。当然,它可以在线性时间内完成。称之为 S 。
然后迭代所有元素并存储两个和:当前元素左侧所有元素的总和以及当前元素右侧所有元素的总和。称他们为 L 和 R 。
对于第一个元素 A [0] :
L = 0
R = S - A[0]
当您转到 A [i] 时,重新计算 L 和 R :
L = L + A[i - 1]
R = R - A[i]
如果 L == R ,则当前元素就是答案。
答案 1 :(得分:1)
在,首先存储总和,然后使用该总和。以下是代码:
public static boolean isSherlock(int arr[])
{
int length = arr.length;
int sum = 0;
for(int i=0; i<length; ++i)
sum += arr[i];
int rightSum = sum-arr[0];
int leftSum = 0;
for(int i=0; i<length-1; ++i){
if(leftSum == rightSum)
return true;
leftSum += arr[i];
rightSum -= arr[i+1];
}
if (leftSum == rightSum)
return true;
return false;
}
答案 2 :(得分:0)
您可以保存上一步计算的左和和和和,如下所示:
int sumLeftStepI=0;
int sumRigthStepI = Arrays.stream(a).sum() - a[0];
for (int i=0; i<a.length;i++){
if(sumLeftStepI==sumRigthStepI){
System.out.println("found element at position a["+i+"]");
}
if(i<a.length-1){
sumLeftStepI+=a[i];
sumRigthStepI-=a[i+1];
}
}
通过这种方式,复杂性应该是O(n)。
答案 3 :(得分:0)
试试这个
rollNumber
答案 4 :(得分:0)
无需为sum 创建单独的变量。将和值分配给右侧或左侧。 这是我提出的效率最高的代码。
同样很明显,对于长度小于3的数组,结果会如此 总是假的。
private static boolean balanceIntArrray(int[] nums) {
int length = nums.length;
if (length < 3) {
return false;
}
int left = nums[0];
int right = 0;
for (int i = 2; i < nums.length; i++) {
right += nums[i];
}
for (int i = 1; i < nums.length - 1; i++) {
if (left == right) {
return true;
}
left += nums[i];
right -= nums[i + 1];
}
return (left == right);
}