在数组中找到一个元素,使得左数组的总和等于右数组的总和
给定一个大小为 n 的数组。找到一个元素,将数组分成两个总和相等的子数组。
例子:
Input: 1 4 2 5
Output: 2
Explanation: If 2 is the partition,
subarrays are : {1, 4} and {5}
Input: 2 3 4 1 4 5
Output: 1
Explanation: If 1 is the partition,
Subarrays are : {2, 3, 4} and {4, 5}
方法1(简单)
考虑从第二个元素开始的每个元素。计算其左侧元素的总和和右侧元素的总和。如果这两个和相同,则返回元素。
方法 2(使用前缀和后缀数组:
We form a prefix and suffix sum arrays
Given array: 1 4 2 5
Prefix Sum: 1 5 7 12
Suffix Sum: 12 11 7 5
Now, we will traverse both prefix arrays.
The index at which they yield equal result,
is the index where the array is partitioned
with equal sum.
下面是上述方法的实现:
C++
#include
using namespace std;
int findElement(int arr[], int n)
{
// Forming prefix sum array from 0
int prefixSum[n];
prefixSum[0] = arr[0];
for (int i = 1; i < n; i++)
prefixSum[i] = prefixSum[i - 1] + arr[i];
// Forming suffix sum array from n-1
int suffixSum[n];
suffixSum[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--)
suffixSum[i] = suffixSum[i + 1] + arr[i];
// Find the point where prefix and suffix
// sums are same.
for (int i = 1; i < n - 1; i++)
if (prefixSum[i] == suffixSum[i])
return arr[i];
return -1;
}
// Driver code
int main()
{
int arr[] = { 1, 4, 2, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << findElement(arr, n);
return 0;
}
Java
// Java program to find an element
// such that sum of right side element
// is equal to sum of left side
public class GFG {
// Finds an element in an array such that
// left and right side sums are equal
static int findElement(int arr[], int n)
{
// Forming prefix sum array from 0
int[] prefixSum = new int[n];
prefixSum[0] = arr[0];
for (int i = 1; i < n; i++)
prefixSum[i] = prefixSum[i - 1] + arr[i];
// Forming suffix sum array from n-1
int[] suffixSum = new int[n];
suffixSum[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--)
suffixSum[i] = suffixSum[i + 1] + arr[i];
// Find the point where prefix and suffix
// sums are same.
for (int i = 1; i < n - 1; i++)
if (prefixSum[i] == suffixSum[i])
return arr[i];
return -1;
}
// Driver code
public static void main(String args[])
{
int arr[] = { 1, 4, 2, 5 };
int n = arr.length;
System.out.println(findElement(arr, n));
}
}
// This code is contributed by Sumit Ghosh
Python 3
# Python 3 Program to find an element
# such that sum of right side element
# is equal to sum of left side
# Function for Finds an element in
# an array such that left and right
# side sums are equal
def findElement(arr, n) :
# Forming prefix sum array from 0
prefixSum = [0] * n
prefixSum[0] = arr[0]
for i in range(1, n) :
prefixSum[i] = prefixSum[i - 1] + arr[i]
# Forming suffix sum array from n-1
suffixSum = [0] * n
suffixSum[n - 1] = arr[n - 1]
for i in range(n - 2, -1, -1) :
suffixSum[i] = suffixSum[i + 1] + arr[i]
# Find the point where prefix
# and suffix sums are same.
for i in range(1, n - 1, 1) :
if prefixSum[i] == suffixSum[i] :
return arr[i]
return -1
# Driver Code
if __name__ == "__main__" :
arr = [ 1, 4, 2, 5]
n = len(arr)
print(findElement(arr, n))
# This code is contributed by ANKITRAI1
C#
// C# program to find an element
// such that sum of right side element
// is equal to sum of left side
using System;
class GFG
{
// Finds an element in an
// array such that left
// and right side sums
// are equal
static int findElement(int []arr,
int n)
{
// Forming prefix sum
// array from 0
int[] prefixSum = new int[n];
prefixSum[0] = arr[0];
for (int i = 1; i < n; i++)
prefixSum[i] = prefixSum[i - 1] +
arr[i];
// Forming suffix sum
// array from n-1
int[] suffixSum = new int[n];
suffixSum[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--)
suffixSum[i] = suffixSum[i + 1] +
arr[i];
// Find the point where prefix
// and suffix sums are same.
for (int i = 1; i < n - 1; i++)
if (prefixSum[i] == suffixSum[i])
return arr[i];
return -1;
}
// Driver code
public static void Main()
{
int []arr = { 1, 4, 2, 5 };
int n = arr.Length;
Console.WriteLine(findElement(arr, n));
}
}
// This code is contributed by anuj_67.
PHP
= 0; $i--)
$suffixSum[$i] = $suffixSum[$i + 1] +
$arr[$i];
// Find the point where prefix
// and suffix sums are same.
for ($i = 1; $i < $n - 1; $i++)
if ($prefixSum[$i] == $suffixSum[$i])
return $arr[$i];
return -1;
}
// Driver code
$arr = array( 1, 4, 2, 5 );
$n = sizeof($arr);
echo findElement($arr, $n);
// This code is contributed
// by ChitraNayal
?>
Javascript
C++
#include
using namespace std;
// Function to compute partition
int findElement(int arr[], int size)
{
int right_sum = 0, left_sum = 0;
// Computing right_sum
for (int i = 1; i < size; i++)
right_sum += arr[i];
// Checking the point of partition
// i.e. left_Sum == right_sum
for (int i = 0, j = 1; j < size; i++, j++) {
right_sum -= arr[j];
left_sum += arr[i];
if (left_sum == right_sum)
return arr[i + 1];
}
return -1;
}
// Driver
int main()
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << findElement(arr, size);
return 0;
}
Java
// Java program to find an element
// such that sum of right side element
// is equal to sum of left side
public class GFG {
// Function to compute partition
static int findElement(int arr[], int size)
{
int right_sum = 0, left_sum = 0;
// Computing right_sum
for (int i = 1; i < size; i++)
right_sum += arr[i];
// Checking the point of partition
// i.e. left_Sum == right_sum
for (int i = 0, j = 1; j < size; i++, j++) {
right_sum -= arr[j];
left_sum += arr[i];
if (left_sum == right_sum)
return arr[i + 1];
}
return -1;
}
// Driver
public static void main(String args[])
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = arr.length;
System.out.println(findElement(arr, size));
}
}
// This code is contributed by Sumit Ghosh
Python 3
# Python 3 Program to find an element
# such that sum of right side element
# is equal to sum of left side
# Function to compute partition
def findElement(arr, size) :
right_sum, left_sum = 0, 0
# Computing right_sum
for i in range(1, size) :
right_sum += arr[i]
i, j = 0, 1
# Checking the point of partition
# i.e. left_Sum == right_sum
while j < size :
right_sum -= arr[j]
left_sum += arr[i]
if left_sum == right_sum :
return arr[i + 1]
j += 1
i += 1
return -1
# Driver Code
if __name__ == "__main__" :
arr = [ 2, 3, 4, 1, 4, 5]
n = len(arr)
print(findElement(arr, n))
# This code is contributed by ANKITRAI1
C#
// C# program to find an
// element such that sum
// of right side element
// is equal to sum of
// left side
using System;
class GFG
{
// Function to compute
// partition
static int findElement(int []arr,
int size)
{
int right_sum = 0,
left_sum = 0;
// Computing right_sum
for (int i = 1; i < size; i++)
right_sum += arr[i];
// Checking the point
// of partition i.e.
// left_Sum == right_sum
for (int i = 0, j = 1;
j < size; i++, j++)
{
right_sum -= arr[j];
left_sum += arr[i];
if (left_sum == right_sum)
return arr[i + 1];
}
return -1;
}
// Driver Code
public static void Main()
{
int []arr = {2, 3, 4, 1, 4, 5};
int size = arr.Length;
Console.WriteLine(findElement(arr, size));
}
}
// This code is contributed
// by anuj_67.
PHP
Javascript
C++
// C++ program to find an element
// such that sum of right side element
// is equal to sum of left side
#include
using namespace std;
// Function to compute
// partition
int findElement(int arr[],
int size)
{
int right_sum = 0,
left_sum = 0;
// Maintains left
// cumulative sum
left_sum = 0;
// Maintains right
// cumulative sum
right_sum = 0;
int i = -1, j = -1;
for(i = 0, j = size - 1;
i < j; i++, j--)
{
left_sum += arr[i];
right_sum += arr[j];
// Keep moving i towards
// center until left_sum
//is found lesser than right_sum
while(left_sum < right_sum &&
i < j)
{
i++;
left_sum += arr[i];
}
// Keep moving j towards
// center until right_sum is
// found lesser than left_sum
while(right_sum < left_sum &&
i < j)
{
j--;
right_sum += arr[j];
}
}
if(left_sum == right_sum && i == j)
return arr[i];
else
return -1;
}
// Driver code
int main()
{
int arr[] = {2, 3, 4,
1, 4, 5};
int size = sizeof(arr) /
sizeof(arr[0]);
cout << (findElement(arr, size));
}
// This code is contributed by shikhasingrajput
Java
// Java program to find an element
// such that sum of right side element
// is equal to sum of left side
public class Gfg {
// Function to compute partition
static int findElement(int arr[], int size)
{
int right_sum = 0, left_sum = 0;
// Maintains left cumulative sum
left_sum = 0;
// Maintains right cumulative sum
right_sum=0;
int i = -1, j = -1;
for( i = 0, j = size-1 ; i < j ; i++, j-- ){
left_sum += arr[i];
right_sum += arr[j];
// Keep moving i towards center until
// left_sum is found lesser than right_sum
while(left_sum < right_sum && i < j){
i++;
left_sum += arr[i];
}
// Keep moving j towards center until
// right_sum is found lesser than left_sum
while(right_sum < left_sum && i < j){
j--;
right_sum += arr[j];
}
}
if(left_sum == right_sum && i == j)
return arr[i];
else
return -1;
}
// Driver code
public static void main(String args[])
{
int arr[] = {2, 3, 4, 1, 4, 5};
int size = arr.length;
System.out.println(findElement(arr, size));
}
}
Python3
# Python3 program to find an element
# such that sum of right side element
# is equal to sum of left side
# Function to compute partition
def findElement(arr, size):
# Maintains left cumulative sum
left_sum = 0;
# Maintains right cumulative sum
right_sum = 0;
i = 0; j = -1;
j = size - 1;
while(i < j):
if(i < j):
left_sum += arr[i];
right_sum += arr[j];
# Keep moving i towards center
# until left_sum is found
# lesser than right_sum
while (left_sum < right_sum and
i < j):
i += 1;
left_sum += arr[i];
# Keep moving j towards center
# until right_sum is found
# lesser than left_sum
while (right_sum < left_sum and
i < j):
j -= 1;
right_sum += arr[j];
j -= 1
i += 1
if (left_sum == right_sum && i == j):
return arr[i];
else:
return -1;
# Driver code
if __name__ == '__main__':
arr = [2, 3, 4,
1, 4, 5];
size = len(arr);
print(findElement(arr, size));
# This code is contributed by shikhasingrajput
C#
// C# program to find an element
// such that sum of right side element
// is equal to sum of left side
using System;
class GFG{
// Function to compute partition
static int findElement(int []arr, int size)
{
int right_sum = 0, left_sum = 0;
// Maintains left cumulative sum
left_sum = 0;
// Maintains right cumulative sum
right_sum = 0;
int i = -1, j = -1;
for(i = 0, j = size - 1; i < j; i++, j--)
{
left_sum += arr[i];
right_sum += arr[j];
// Keep moving i towards center until
// left_sum is found lesser than right_sum
while (left_sum < right_sum && i < j)
{
i++;
left_sum += arr[i];
}
// Keep moving j towards center until
// right_sum is found lesser than left_sum
while (right_sum < left_sum && i < j)
{
j--;
right_sum += arr[j];
}
}
if (left_sum == right_sum && i == j)
return arr[i];
else
return -1;
}
// Driver code
public static void Main(String []args)
{
int []arr = { 2, 3, 4, 1, 4, 5 };
int size = arr.Length;
Console.WriteLine(findElement(arr, size));
}
}
// This code is contributed by Amit Katiyar
Javascript
C++
#include
using namespace std;
// Function to find equilibrium point
// a: input array
// n: size of array
int equilibriumPoint(int a[], int n)
{
// Here we define two pointers to the array -> start =
// 0, end = n-1 Two variables to take care of sum ->
// left_sum = 0, right_sum = 0
int i = 0, start = 0, end = n - 1, left_sum = 0,
right_sum = 0;
for (i = 0; i < n; i++) {
// if the equilibrium element is found our start
// will be equal to end variable and left_sum will
// be equal right_sum => return the equilibrium
// element
if (start == end && right_sum == left_sum)
return a[start];
// if start is equal to end variable but left_sum is
// not equal right_sum => no equilibrium element
// return -1
if (start == end)
return -1;
// if left_sum > right_sum => add the current end
// element to the right_sum and decrement end
if (left_sum > right_sum) {
right_sum += a[end];
end--;
}
// if right_sum < left_sum => add the current start
// element to the left_sum and increment start
else if (right_sum > left_sum) {
left_sum += a[start];
start++;
}
/*
if left_sum is equal right_sum but start is not
equal to end => we are still in the middle of
algorithm even though we found that left_sum is
equal right_sum we haven't got that one required
equilibrium element (So, in this case add the
current end element to the right_sum and
decrement end (or) add the current start element
to the left_sum and increment start, to make our
algorithm continue further)
*/
else {
right_sum += a[end];
end--;
}
}
// When there is only one element in array our algorithm
// exits without entering for loop So we can check if our
// functions enters the loop if not we can directly
// return the value as answer
if (!i) {
return a[0];
}
}
// Driver code
int main()
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << (equilibriumPoint(arr, size));
}
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG
{
// Function to find equilibrium point
// a: input array
// n: size of array
static int equilibriumPoint(int a[], int n)
{
// Here we define two pointers to the array -> start =
// 0, end = n-1 Two variables to take care of sum ->
// left_sum = 0, right_sum = 0
int i = 0, start = 0, end = n - 1, left_sum = 0,
right_sum = 0;
for (i = 0; i < n; i++)
{
// if the equilibrium element is found our start
// will be equal to end variable and left_sum will
// be equal right_sum => return the equilibrium
// element
if (start == end && right_sum == left_sum)
return a[start];
// if start is equal to end variable but left_sum is
// not equal right_sum => no equilibrium element
// return -1
if (start == end)
return -1;
// if left_sum > right_sum => add the current end
// element to the right_sum and decrement end
if (left_sum > right_sum)
{
right_sum += a[end];
end--;
}
// if right_sum < left_sum => add the current start
// element to the left_sum and increment start
else if (right_sum > left_sum)
{
left_sum += a[start];
start++;
}
/*
if left_sum is equal right_sum but start is not
equal to end => we are still in the middle of
algorithm even though we found that left_sum is
equal right_sum we haven't got that one required
equilibrium element (So, in this case add the
current end element to the right_sum and
decrement end (or) add the current start element
to the left_sum and increment start, to make our
algorithm continue further)
*/
else {
right_sum += a[end];
end--;
}
}
// When there is only one element in array our algorithm
// exits without entering for loop So we can check if our
// functions enters the loop if not we can directly
// return the value as answer
if (i == 0)
{
return a[0];
}
return -1;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = arr.length;
System.out.println(equilibriumPoint(arr, size));
}
}
// This code is contributed by avanitrachhadiya2155
Javascript
C#
using System;
public class GFG{
// Function to find equilibrium point
// a: input array
// n: size of array
static int equilibriumPoint(int[] a, int n)
{
// Here we define two pointers to the array -> start =
// 0, end = n-1 Two variables to take care of sum ->
// left_sum = 0, right_sum = 0
int i = 0, start = 0, end = n - 1, left_sum = 0,
right_sum = 0;
for (i = 0; i < n; i++)
{
// if the equilibrium element is found our start
// will be equal to end variable and left_sum will
// be equal right_sum => return the equilibrium
// element
if (start == end && right_sum == left_sum)
return a[start];
// if start is equal to end variable but left_sum is
// not equal right_sum => no equilibrium element
// return -1
if (start == end)
return -1;
// if left_sum > right_sum => add the current end
// element to the right_sum and decrement end
if (left_sum > right_sum)
{
right_sum += a[end];
end--;
}
// if right_sum < left_sum => add the current start
// element to the left_sum and increment start
else if (right_sum > left_sum)
{
left_sum += a[start];
start++;
}
/*
if left_sum is equal right_sum but start is not
equal to end => we are still in the middle of
algorithm even though we found that left_sum is
equal right_sum we haven't got that one required
equilibrium element (So, in this case add the
current end element to the right_sum and
decrement end (or) add the current start element
to the left_sum and increment start, to make our
algorithm continue further)
*/
else {
right_sum += a[end];
end--;
}
}
// When there is only one element in array our algorithm
// exits without entering for loop So we can check if our
// functions enters the loop if not we can directly
// return the value as answer
if (i == 0)
{
return a[0];
}
return -1;
}
// Driver code
static public void Main (){
int[] arr = { 2, 3, 4, 1, 4, 5 };
int size = arr.Length;
Console.WriteLine(equilibriumPoint(arr, size));
}
}
输出
2
方法 3(节省空间)
我们计算整个数组的总和,除了 right_sum 中的第一个元素,认为它是分区元素。现在,我们从左到右遍历数组,从 right_sum 中减去一个元素,然后在 left_sum 中添加一个元素。在 right_sum 等于 left_sum 处,我们得到了分区。
下面是实现:
C++
#include
using namespace std;
// Function to compute partition
int findElement(int arr[], int size)
{
int right_sum = 0, left_sum = 0;
// Computing right_sum
for (int i = 1; i < size; i++)
right_sum += arr[i];
// Checking the point of partition
// i.e. left_Sum == right_sum
for (int i = 0, j = 1; j < size; i++, j++) {
right_sum -= arr[j];
left_sum += arr[i];
if (left_sum == right_sum)
return arr[i + 1];
}
return -1;
}
// Driver
int main()
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << findElement(arr, size);
return 0;
}
Java
// Java program to find an element
// such that sum of right side element
// is equal to sum of left side
public class GFG {
// Function to compute partition
static int findElement(int arr[], int size)
{
int right_sum = 0, left_sum = 0;
// Computing right_sum
for (int i = 1; i < size; i++)
right_sum += arr[i];
// Checking the point of partition
// i.e. left_Sum == right_sum
for (int i = 0, j = 1; j < size; i++, j++) {
right_sum -= arr[j];
left_sum += arr[i];
if (left_sum == right_sum)
return arr[i + 1];
}
return -1;
}
// Driver
public static void main(String args[])
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = arr.length;
System.out.println(findElement(arr, size));
}
}
// This code is contributed by Sumit Ghosh
Python3
# Python 3 Program to find an element
# such that sum of right side element
# is equal to sum of left side
# Function to compute partition
def findElement(arr, size) :
right_sum, left_sum = 0, 0
# Computing right_sum
for i in range(1, size) :
right_sum += arr[i]
i, j = 0, 1
# Checking the point of partition
# i.e. left_Sum == right_sum
while j < size :
right_sum -= arr[j]
left_sum += arr[i]
if left_sum == right_sum :
return arr[i + 1]
j += 1
i += 1
return -1
# Driver Code
if __name__ == "__main__" :
arr = [ 2, 3, 4, 1, 4, 5]
n = len(arr)
print(findElement(arr, n))
# This code is contributed by ANKITRAI1
C#
// C# program to find an
// element such that sum
// of right side element
// is equal to sum of
// left side
using System;
class GFG
{
// Function to compute
// partition
static int findElement(int []arr,
int size)
{
int right_sum = 0,
left_sum = 0;
// Computing right_sum
for (int i = 1; i < size; i++)
right_sum += arr[i];
// Checking the point
// of partition i.e.
// left_Sum == right_sum
for (int i = 0, j = 1;
j < size; i++, j++)
{
right_sum -= arr[j];
left_sum += arr[i];
if (left_sum == right_sum)
return arr[i + 1];
}
return -1;
}
// Driver Code
public static void Main()
{
int []arr = {2, 3, 4, 1, 4, 5};
int size = arr.Length;
Console.WriteLine(findElement(arr, size));
}
}
// This code is contributed
// by anuj_67.
PHP
Javascript
输出
1
方法 4(时间和空间高效)
We define two pointers i and j to traverse the array from left and right,
left_sum and right_sum to store sum from right and left respectively
If left_sum is lesser than increment i and if right_sum is lesser than decrement j
and, find a position where left_sum == right_sum and i and j are next to each other
注意:此解决方案仅适用于数组仅包含正元素的情况。
下面是上述方法的实现:
C++
// C++ program to find an element
// such that sum of right side element
// is equal to sum of left side
#include
using namespace std;
// Function to compute
// partition
int findElement(int arr[],
int size)
{
int right_sum = 0,
left_sum = 0;
// Maintains left
// cumulative sum
left_sum = 0;
// Maintains right
// cumulative sum
right_sum = 0;
int i = -1, j = -1;
for(i = 0, j = size - 1;
i < j; i++, j--)
{
left_sum += arr[i];
right_sum += arr[j];
// Keep moving i towards
// center until left_sum
//is found lesser than right_sum
while(left_sum < right_sum &&
i < j)
{
i++;
left_sum += arr[i];
}
// Keep moving j towards
// center until right_sum is
// found lesser than left_sum
while(right_sum < left_sum &&
i < j)
{
j--;
right_sum += arr[j];
}
}
if(left_sum == right_sum && i == j)
return arr[i];
else
return -1;
}
// Driver code
int main()
{
int arr[] = {2, 3, 4,
1, 4, 5};
int size = sizeof(arr) /
sizeof(arr[0]);
cout << (findElement(arr, size));
}
// This code is contributed by shikhasingrajput
Java
// Java program to find an element
// such that sum of right side element
// is equal to sum of left side
public class Gfg {
// Function to compute partition
static int findElement(int arr[], int size)
{
int right_sum = 0, left_sum = 0;
// Maintains left cumulative sum
left_sum = 0;
// Maintains right cumulative sum
right_sum=0;
int i = -1, j = -1;
for( i = 0, j = size-1 ; i < j ; i++, j-- ){
left_sum += arr[i];
right_sum += arr[j];
// Keep moving i towards center until
// left_sum is found lesser than right_sum
while(left_sum < right_sum && i < j){
i++;
left_sum += arr[i];
}
// Keep moving j towards center until
// right_sum is found lesser than left_sum
while(right_sum < left_sum && i < j){
j--;
right_sum += arr[j];
}
}
if(left_sum == right_sum && i == j)
return arr[i];
else
return -1;
}
// Driver code
public static void main(String args[])
{
int arr[] = {2, 3, 4, 1, 4, 5};
int size = arr.length;
System.out.println(findElement(arr, size));
}
}
Python3
# Python3 program to find an element
# such that sum of right side element
# is equal to sum of left side
# Function to compute partition
def findElement(arr, size):
# Maintains left cumulative sum
left_sum = 0;
# Maintains right cumulative sum
right_sum = 0;
i = 0; j = -1;
j = size - 1;
while(i < j):
if(i < j):
left_sum += arr[i];
right_sum += arr[j];
# Keep moving i towards center
# until left_sum is found
# lesser than right_sum
while (left_sum < right_sum and
i < j):
i += 1;
left_sum += arr[i];
# Keep moving j towards center
# until right_sum is found
# lesser than left_sum
while (right_sum < left_sum and
i < j):
j -= 1;
right_sum += arr[j];
j -= 1
i += 1
if (left_sum == right_sum && i == j):
return arr[i];
else:
return -1;
# Driver code
if __name__ == '__main__':
arr = [2, 3, 4,
1, 4, 5];
size = len(arr);
print(findElement(arr, size));
# This code is contributed by shikhasingrajput
C#
// C# program to find an element
// such that sum of right side element
// is equal to sum of left side
using System;
class GFG{
// Function to compute partition
static int findElement(int []arr, int size)
{
int right_sum = 0, left_sum = 0;
// Maintains left cumulative sum
left_sum = 0;
// Maintains right cumulative sum
right_sum = 0;
int i = -1, j = -1;
for(i = 0, j = size - 1; i < j; i++, j--)
{
left_sum += arr[i];
right_sum += arr[j];
// Keep moving i towards center until
// left_sum is found lesser than right_sum
while (left_sum < right_sum && i < j)
{
i++;
left_sum += arr[i];
}
// Keep moving j towards center until
// right_sum is found lesser than left_sum
while (right_sum < left_sum && i < j)
{
j--;
right_sum += arr[j];
}
}
if (left_sum == right_sum && i == j)
return arr[i];
else
return -1;
}
// Driver code
public static void Main(String []args)
{
int []arr = { 2, 3, 4, 1, 4, 5 };
int size = arr.Length;
Console.WriteLine(findElement(arr, size));
}
}
// This code is contributed by Amit Katiyar
Javascript
输出
1
由于所有循环都从最后更新的 i 和 j 指针开始遍历并且不相互交叉,因此它们最终运行 n 次。
时间复杂度- O(n)
辅助空间- O(1)
方法5(高效算法):
- 这里我们定义了两个指向数组的指针 -> start = 0, end = n-1
- 两个变量来处理 sum -> left_sum = 0, right_sum = 0
这里我们的算法是这样的:
- 我们初始化for循环直到数组的整个大小
- 基本上我们检查是否 left_sum > right_sum => 将当前结束元素添加到right_sum并减少结束
- 如果 right_sum < left_sum => 将当前起始元素添加到left_sum并递增start
- 通过这两个条件,我们确保left_sum和right_sum接近平衡,因此我们可以轻松得出我们的解决方案
- 为了在所有测试用例中实现这一点,我们需要在我们的逻辑中添加几个条件语句:
- 如果找到平衡元素,我们的start将等于end变量, left_sum将等于right_sum =>返回平衡元素(这里我们说 start == end 因为我们在添加当前开始/结束值后递增/递减指针到各自的总和。因此,如果找到平衡元素,开始和结束应该在同一位置)
- 如果start等于end变量但left_sum不等于right_sum =>没有平衡元素返回 -1
- 如果 left_sum等于right_sum,但start不等于end =>即使我们发现left_sum等于right_sum ,我们仍然处于算法的中间,但我们没有得到所需的平衡元素(因此,在这种情况下,将当前结束元素添加到right_sum并减少end (或)将当前开始元素添加到left_sum并增加start,以使我们的算法进一步继续)。
- 即使在这里,也需要处理一个测试用例:
- 当数组中只有一个元素时,我们的算法退出而不进入循环。
- 所以我们可以检查我们的函数是否进入循环,如果没有,我们可以直接返回值作为答案。
下面是上述方法的实现:
C++
#include
using namespace std;
// Function to find equilibrium point
// a: input array
// n: size of array
int equilibriumPoint(int a[], int n)
{
// Here we define two pointers to the array -> start =
// 0, end = n-1 Two variables to take care of sum ->
// left_sum = 0, right_sum = 0
int i = 0, start = 0, end = n - 1, left_sum = 0,
right_sum = 0;
for (i = 0; i < n; i++) {
// if the equilibrium element is found our start
// will be equal to end variable and left_sum will
// be equal right_sum => return the equilibrium
// element
if (start == end && right_sum == left_sum)
return a[start];
// if start is equal to end variable but left_sum is
// not equal right_sum => no equilibrium element
// return -1
if (start == end)
return -1;
// if left_sum > right_sum => add the current end
// element to the right_sum and decrement end
if (left_sum > right_sum) {
right_sum += a[end];
end--;
}
// if right_sum < left_sum => add the current start
// element to the left_sum and increment start
else if (right_sum > left_sum) {
left_sum += a[start];
start++;
}
/*
if left_sum is equal right_sum but start is not
equal to end => we are still in the middle of
algorithm even though we found that left_sum is
equal right_sum we haven't got that one required
equilibrium element (So, in this case add the
current end element to the right_sum and
decrement end (or) add the current start element
to the left_sum and increment start, to make our
algorithm continue further)
*/
else {
right_sum += a[end];
end--;
}
}
// When there is only one element in array our algorithm
// exits without entering for loop So we can check if our
// functions enters the loop if not we can directly
// return the value as answer
if (!i) {
return a[0];
}
}
// Driver code
int main()
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << (equilibriumPoint(arr, size));
}
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG
{
// Function to find equilibrium point
// a: input array
// n: size of array
static int equilibriumPoint(int a[], int n)
{
// Here we define two pointers to the array -> start =
// 0, end = n-1 Two variables to take care of sum ->
// left_sum = 0, right_sum = 0
int i = 0, start = 0, end = n - 1, left_sum = 0,
right_sum = 0;
for (i = 0; i < n; i++)
{
// if the equilibrium element is found our start
// will be equal to end variable and left_sum will
// be equal right_sum => return the equilibrium
// element
if (start == end && right_sum == left_sum)
return a[start];
// if start is equal to end variable but left_sum is
// not equal right_sum => no equilibrium element
// return -1
if (start == end)
return -1;
// if left_sum > right_sum => add the current end
// element to the right_sum and decrement end
if (left_sum > right_sum)
{
right_sum += a[end];
end--;
}
// if right_sum < left_sum => add the current start
// element to the left_sum and increment start
else if (right_sum > left_sum)
{
left_sum += a[start];
start++;
}
/*
if left_sum is equal right_sum but start is not
equal to end => we are still in the middle of
algorithm even though we found that left_sum is
equal right_sum we haven't got that one required
equilibrium element (So, in this case add the
current end element to the right_sum and
decrement end (or) add the current start element
to the left_sum and increment start, to make our
algorithm continue further)
*/
else {
right_sum += a[end];
end--;
}
}
// When there is only one element in array our algorithm
// exits without entering for loop So we can check if our
// functions enters the loop if not we can directly
// return the value as answer
if (i == 0)
{
return a[0];
}
return -1;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 2, 3, 4, 1, 4, 5 };
int size = arr.length;
System.out.println(equilibriumPoint(arr, size));
}
}
// This code is contributed by avanitrachhadiya2155
Javascript
C#
using System;
public class GFG{
// Function to find equilibrium point
// a: input array
// n: size of array
static int equilibriumPoint(int[] a, int n)
{
// Here we define two pointers to the array -> start =
// 0, end = n-1 Two variables to take care of sum ->
// left_sum = 0, right_sum = 0
int i = 0, start = 0, end = n - 1, left_sum = 0,
right_sum = 0;
for (i = 0; i < n; i++)
{
// if the equilibrium element is found our start
// will be equal to end variable and left_sum will
// be equal right_sum => return the equilibrium
// element
if (start == end && right_sum == left_sum)
return a[start];
// if start is equal to end variable but left_sum is
// not equal right_sum => no equilibrium element
// return -1
if (start == end)
return -1;
// if left_sum > right_sum => add the current end
// element to the right_sum and decrement end
if (left_sum > right_sum)
{
right_sum += a[end];
end--;
}
// if right_sum < left_sum => add the current start
// element to the left_sum and increment start
else if (right_sum > left_sum)
{
left_sum += a[start];
start++;
}
/*
if left_sum is equal right_sum but start is not
equal to end => we are still in the middle of
algorithm even though we found that left_sum is
equal right_sum we haven't got that one required
equilibrium element (So, in this case add the
current end element to the right_sum and
decrement end (or) add the current start element
to the left_sum and increment start, to make our
algorithm continue further)
*/
else {
right_sum += a[end];
end--;
}
}
// When there is only one element in array our algorithm
// exits without entering for loop So we can check if our
// functions enters the loop if not we can directly
// return the value as answer
if (i == 0)
{
return a[0];
}
return -1;
}
// Driver code
static public void Main (){
int[] arr = { 2, 3, 4, 1, 4, 5 };
int size = arr.Length;
Console.WriteLine(equilibriumPoint(arr, size));
}
}
输出
1
时间复杂度:O(n)
空间复杂度:O(1)