A zero-indexed array given & An equilibrium index of this array [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
A zero-indexed array A consisting of N integers is given. An equilibrium index of this array is any integer P such that 0 ≤ P < N and the sum of elements of lower indices is equal to the sum of elements of higher indices, i.e.
A[0] + A[1] + ... + A[P−1] = A[P+1] + ... + A[N−2] + A[N−1].
Sum of zero elements is assumed to be equal to 0. This can happen if P = 0 or if P = N−1.
For example, consider the following array A consisting of N = 8 elements:
A[0] = -1
A[1] = 3
A[2] = -4
A[3] = 5
A[4] = 1
A[5] = -6
A[6] = 2
A[7] = 1
P = 1 is an equilibrium index of this array, because:
A[0] = −1 = A[2] + A[3] + A[4] + A[5] + A[6] + A[7]
P = 3 is an equilibrium index of this array, because:
A[0] + A[1] + A[2] = −2 = A[4] + A[5] + A[6] + A[7]
P = 7 is also an equilibrium index, because:
A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] = 0
and there are no elements with indices greater than 7.
P = 8 is not an equilibrium index, because it does not fulfill the condition 0 ≤ P < N.
Now i have to write a function:
int solution(int A[], int N);
that, given a zero-indexed array A consisting of N integers, returns any of its equilibrium indices. The function should return −1 if no equilibrium index exists.
For example, given array A shown above, the function may return 1, 3 or 7, as explained above.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
here have some Complexity:
Elements of input arrays can be modified.

100% - Java
int solution(int A[], int N) {
long sum = 0;
for (int i = 0; i < A.length; i++) {
sum += (long) A[i];
}
long leftSum = 0;
long rightSum = 0;
for (int i = 0; i < A.length; i++) {
rightSum = sum - (leftSum + A[i]);
if (leftSum == rightSum) {
return i;
}
leftSum += A[i];
}
return -1;
}
}

100% scored with c#
using System;
class Solution {
public int solution(int[] A) {
// First calculate sum of complete array as `sum_right`
long sum_right = 0;
for (int i = 0; i < A.Length; i++)
{
sum_right += A[i];
}
// start calculating sum from left side (lower index) as `sum_left`
// in each iteration subtract A[i] from complete array sum - `sum_right`
long sum_left = 0;
for (int p = 0; p < A.Length; p++)
{
sum_left += p - 1 < 0 ? 0: A[p-1];
sum_right -= A[p];
if (sum_left == sum_right)
{
return p;
}
}
return -1;
}
}

100 Score in Javascript
function solution(V) {
var sum = 0;
for (i=0; i < V.length; i++) {
sum += V[i];
}
var leftSum= 0;
var rightSum = 0;
for (j=0; j < V.length; j++) {
rightSum = sum - (leftSum + V[j]);
if(leftSum == rightSum) {
return j;
}
leftSum += V[j];
}
return -1;
}

In C++ (because that was one of the original tags, though it looks like it has been removed...)
int solution(int a[], int N){
int left;
int right;
for(int i = 0; i < N; i++){
left = 0;
right = 0;
for(int t = 0; t < N; t++){
if(t < i) left += a[t];
else if(t > i) right += a[t];
else continue;
}
if(left == right) return i;
}
return -1;
}
...
int demo[] = {-1, 3, -4, 5, 1, -6, 2, 1};
cout << solution(demo,sizeof(demo)/sizeof(*demo));
if you want to see all the indices...
if(left == right) cout << "Equilibrium Index: " << i << endl;
I find it odd it doesn't need to return an array of indices; that said, should you need it that's not too hard to implement with some slight modification

The answer is posted in this blog: http://blog.codility.com/2011/03/solutions-for-task-equi.html. In order to avoid O(N^2) and achieve O(N) performance:
The key observation for better running time is to update the left/right sums in constant time instead of recomputing them from the scratch.
int equi(int arr[], int n)
{
if (n==0) return -1;
long long sum = 0;
int i;
for(i=0;i<n;i++) sum+=(long long) arr[i];
long long sum_left = 0;
for(i=0;i<n;i++) {
long long sum_right = sum - sum_left - (long long) arr[i];
if (sum_left == sum_right) return i;
sum_left += (long long) arr[i];
}
return -1;
}

Here is the java equivalent
public static int equilibriumIndex(int[] array) {
int INDEX_NOT_FOUND = -1;
int rSum = 0, lSum = 0;
for (int index = 0; index < array.length; index++) {
rSum += array[index];
}
for (int index = 0; index < array.length; index++) {
lSum += (index==0) ? 0 : array[index -1];// cumulative sum before (left sum) the current index
rSum -= array[index]; // sum after (right sum) the current index onwards
if (lSum == rSum) { // if both sums, cumulative sum before the current index and cumulative sum after the current index is equal, we got the equilibrium index
return index;
}
}
return INDEX_NOT_FOUND;
}
Here is how you would test it
#Test
public void equilibriumTest() {
int result = ArrayUtils.equilibriumIndex(new int[]{1,2,3,1,6});
assertThat(result, equalTo(3));
}

Dynamic programming approach. O(N) time. O(2N) space.
Keep two tables (arrays), tableBefore and tableAfter.
tableBefore has sum up to index i for every i; i -> 1 to N.
tableAfter has sum up to index i for every i; i -> N to 1.
Afterwards loops and compare every index in tableBefore and tableAfter. If it's equal, that's your equilibrium index.
public static int EquilibriumIndex2(int[] a) {
int len = a.length;
int[] tableBefore = new int[len];
int[] tableAfter = new int[len];
tableBefore[0] = 0;
for (int i = 1; i < len; i++) {
tableBefore[i] = tableBefore[i - 1] + a[i - 1];
}
//System.out.println("tableBefore: " + Arrays.toString(tableBefore));
tableAfter[len - 1] = 0;
for (int i = len - 2; i >= 0; i--) {
tableAfter[i] = tableAfter[i + 1] + a[i + 1];
}
//System.out.println("tableAfter: " + java.util.Arrays.toString(tableAfter));
for (int j = 0; j < len; j++) {
if (tableAfter[j] == tableBefore[j]) {
return j;
}
}
return -1;
}

You can use the sums approach to solve this. Whenever sum from left = sum from right, you have an equilibrium point.
public int solution(int[] A) {
int[] sumLeft = new int[A.length];
int[] sumRight = new int[A.length];
sumLeft[0] = A[0];
sumRight[A.length-1] = A[A.length-1];
for (int i=1; i<A.length; i++){
sumLeft[i] = A[i] + sumLeft[i-1];
}
for (int i=A.length-2; i>=0; i--) {
sumRight[i] = sumRight[i+1] + A[i];
}
for (int i=0; i<A.length; i++) {
if (sumLeft[i]==sumRight[i]) {
return i;
}
}
return -1;
}

The straightforward approach looks the following way.
First of all you need to calculate the sum of all elements of the array
For example if you have the array in C++
int a[] = { -1, 3, -4, 5, 1, -6, 2, 1 };
then you can use an ordinary loop to calculate the sum or standard algorithm std::accumulate declared in header <numeric>
For example
long long int right_sum =
std::accumulate( std::begin( a ), std::end( a ), 0ll );
The sum of the elements of the left subsequence initially is equal to zero
long long int left_sum = 0;
Then you can apply standard algorithm std::find_if with an appropriate lambda-expression or again write an ordinary loop as for example
for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
right_sum -= a[i];
if ( left_sum == right_sum ) std::cout << i << ' ';
left_sum += a[i];
}
The result will be
1 3 7

My answer in Swift 3.0
public func solution(_ A : inout [Int]) -> Int {
var nElements = A.count
var equilibriumIndexArray = [Int]() /* to store all possible indices */
var equilibriumIndex = -1
for fixedIndex in 0..<nElements{
var sumLeft = 0
var sumRight = 0
//Sum the left part
for index in 0..<fixedIndex
{
sumLeft += A[index]
}
//Sum the right part
for index in fixedIndex+1..<nElements
{
sumRight += A[index]
}
//Check for equilibrium
if sumLeft == sumRight
{
equilibriumIndexArray.append(fixedIndex)
}
}
//pick a random element from the list of possible answers
if equilibriumIndexArray.count > 0
{
let randomIndex = Int(arc4random_uniform(UInt32(equilibriumIndexArray.count)))
equilibriumIndex = equilibriumIndexArray[randomIndex]
}
return equilibriumIndex
}

in python :)
def solution(A):
INDEX_NOT_FOUND = -1
right_sum = 0
left_sum = 0
for item in range(0, len(A)):
right_sum += A[item]
for item in range(0, len(A)):
if item == 0:
left_sum += 0
else:
left_sum += A[item -1]
right_sum -= A[item]
if left_sum == right_sum:
return item
return INDEX_NOT_FOUND;

100% - PHP
function solution(array $a)
{
$result = [];
for($i = 0; $count = count($a), $i < $count; $i++) {
if(sumLeft($a, $i-1) === sumRight($a, $i+1)) {
$result[] = $i;
}
}
return count($result) ? $result : -1;
}
function sumRight(array $a, int $position): int
{
return array_sum(array_slice($a, $position));;
}
function sumLeft(array $a, int $position): int
{
return array_sum(array_slice($a, 0, $position + 1));
}
echo "<pre>";
print_r(solution([-1, 3, -4, 5, 1, -6, 2, 1]));
output:
Array
(
[0] => 1
[1] => 3
[2] => 7
)

Simple Solution :
steps :
1) Check (Array = null)
Then Print “No Equilibrium point present as the array is NULL”
2) Check (length of Array = 1)
Then Print "Equilibrium_Index = 0" => Only single element present in array which is the equilibrium point
3) Check (Length of Array > 1)
Loop (Array Index 1 to Length-1)
Consider each index as equilibrium point
Check (sum of elements below equilibrium point = sum of elements above equilibrium poin)
Yes => equilibrium_index = i (break the loop)
No => continue step 3 with next value of loop counter
4) if control is not returned from step 3 means the equilibrium point is not present in loop
Then Print "No equilibrium point present in array."
Please find below code for same :
public int findSum(int equillibrium,int a[],int flag)
{
/*Flag - It represents whether sum is required for left side of equilibrium
point or right side of equilibrium point
*Flag = 0 => Sum is required for left side of equilibrium point
*Flag = 1 => Sum is required for right side of equilibrium point
*/
int lowlimit = 0, uplimit = a.length-1, i ,sum = 0;
if(flag==0)
uplimit = equillibrium - 1;
else
lowlimit = equillibrium + 1;
for(i=lowlimit ; i<=uplimit; i++)
sum = sum + a[i];
return sum;
}
public int findEquillibriumPoint(int a[])
{
int i = 0; //Loop Counter
//Since only one element is present it is at equilibrium only and index of equillibrium point is index of single element i.e 0
if(a.length==1)
return 0;
else
{
for(i=1;i<a.length;i++)
{
if(findSum(i,a,0)==findSum(i,a,1)) //checking if some of lower half from equilibrium point is equal to sum of upper half
return i; //if equilibrium point is found return the index of equilibrium point
}
}
return -1;//if equilibrium point is not present in array then return -1
}

For the lazy ones and PHP developers:
$A = [];
$A[0] = -1;
$A[1] = 3;
$A[2] = -4;
$A[3] = 5;
$A[4] = 1;
$A[5] = -6;
$A[6] = 2;
$A[7] = 1;
echo solution($A) . "\n";
function solution($A)
{
$sum = 0;
for ($i=0; $i < count($A); $i++) {
$sum += $A[$i];
}
$sumRight = 0;
$sumLeft = 0;
for ($j=0; $j < count($A); $j++) {
$sumRight = $sum - ($sumLeft + $A[$j]);
if ($sumLeft == $sumRight) {
return $j;
}
$sumLeft += $A[$j];
}
return -1;
}
Complexity O(N)

100 Score in Ruby
def equilibrium(a)
sum = 0
n = a.length
left_sum = 0
right_sum = 0
n.times do |i|
sum += a[i]
end
n.times do |i|
right_sum = sum - left_sum - a[i]
if right_sum == left_sum
return i
end
left_sum += a[i]
end
return -1
end

Fully tested C#
using System;
class Program
{
static int Function1(int[] arr, int n)
{
int i, j;
int leftsum;
int rightsum;
for (i = 0; i < n; ++i)
{
leftsum = 0;
rightsum = 0;
if(i == 0)
{
leftsum = 0;
for (j = 0; j < n; j++)
{
rightsum += arr[j];
}
if (leftsum == rightsum)
return i;
}
for (j = 0; j < i; j++)
{
leftsum += arr[j];
}
if (n-1 != j)
{
for (j = i + 1; j < n; j++)
{
rightsum += arr[j];
}
}
else
{
rightsum = arr[n-1];
}
if (leftsum == rightsum)
return i;
}
return -1;
}
public static void Main(string[] args)
{
int[] arr = { 1, 5, -8, 0, -2 };
int arr_size = arr.Length;
Console.Write(Function1(arr, arr_size));
}
}

Related

Sorting 2 arrays at once without extra space

How should I optimize my code?
Given two sorted arrays arr1[] of size N and arr2[] of size M. Each array is sorted in non-decreasing order. Merge the two arrays into one sorted array in non-decreasing order without using any extra space.
Example 1:
Input:
N = 4, M = 5
arr1[] = {1, 3, 5, 7}
arr2[] = {0, 2, 6, 8, 9}
Output:
0 1 2 3 5 6 7 8 9
Explanation: Since you can't use any extra space, modify the given arrays to form:
arr1[] = {0, 1, 2, 3}
arr2[] = {5, 6, 7, 8, 9}
class Solution {
public void merge(int arr1[], int arr2[], int n, int m) {
for (int k = 0; k < n; k++) {
boolean c = false;
if (arr1[k] > arr2[0]) {
int temp = arr1[k];
arr1[k] = arr2[0];
arr2[0] = temp;
c = true;
}
if (c) {
int minIndex = 0;
for (int i = 0; i < m; i++) {
if (arr2[i] < arr2[minIndex])
minIndex = i;
}
int t = arr2[minIndex];
arr2[minIndex] = arr2[0];
arr2[0] = t;
}
}
for (int i = 0; i < m - 1; i++) {
int minIndex = i;
for (int j = i; j < m; j++) {
if (arr2[j] < arr2[minIndex]) {
minIndex = j;
}
}
int temp = arr2[i];
arr2[i] = arr2[minIndex];
arr2[minIndex] = temp;
}
}
}
Here is a slightly simpler version. It still has the same quadratic time complexity of O(n*m) but executes 10 times faster than the posted code, so it does qualify as an optimized version:
class Solution {
public void merge_chqrlie(int arr1[], int arr2[], int n, int m) {
if (n > 0 && m > 0) {
// for each element of arr2
for (int i1 = 0, i2 = 0, j, k = 0; k < m; k++) {
// shift it left inside arr2
for (j = k; j > i2 && arr2[j-1] > arr2[j]; j--) {
int temp = arr2[j-1];
arr2[j-1] = arr2[j];
arr2[j] = temp;
}
// if it moved to arr2[0] and is smaller than the last element of arr1
if (j == 0 && arr1[n-1] > arr2[0]) {
// move it to arr1[n-1]
int temp = arr1[n-1];
arr1[n-1] = arr2[0];
arr2[0] = temp;
// and further shift it into arr1
for (j = n - 1; j > i1 && arr1[j-1] > arr1[j]; j--) {
temp = arr1[j-1];
arr1[j-1] = arr1[j];
arr1[j] = temp;
}
// update i1: the finalized portion of arr1
i1 = j + 1;
} else {
// update i2: the finalized portion of arr2
i2 = j + 1;
}
}
}
}
}
Merging without using extra space is a very strict constraint: do you consider local variables to be extra space? If you allow for limited extra space, such as a single array of 128 elements, much faster solutions can be found that perform 500 to 2000 times faster than the posted code for moderately large arrays (above 5000 elements) but still exhibit quadratic time complexity for large arrays.
Here is an advanced solution (1000x faster for arrays of 500k elements):
class Solution {
static int tmp_size = 128;
static int *tmp;
public void merge_chqrlie2(int arr1[], int arr2[], int n, int m) {
if (!tmp)
tmp = new int[tmp_size];
for (int chunk = tmp_size; n > 0; n -= chunk, arr1 += chunk) {
int i = 0, j = 0, k = 0;
if (chunk > n)
chunk = n;
for (k = 0; k < chunk; k++)
tmp[k] = arr1[k];
for (k = 0; k < chunk; k++) {
if (j >= m || tmp[i] <= arr2[j])
arr1[k] = tmp[i++];
else
arr1[k] = arr2[j++];
}
for (k = 0; i < chunk; k++) {
if (j >= m || tmp[i] <= arr2[j])
arr2[k] = tmp[i++];
else
arr2[k] = arr2[j++];
}
}
}
}
The temporary storage would be allocated on the stack (automatic storage) in languages such as C or C++ for optimum efficiency.
Here is an even more efficient one, with better performance on pathological samples and 2,5x faster on random contents:
void merge_chqrlie3(int arr1[], int arr2[], size_t n, size_t m) {
int tmp[128];
size_t i2 = 0;
for (size_t chunk = sizeof(tmp) / sizeof(*tmp); n > 0; n -= chunk, arr1 += chunk) {
size_t i = 0, j = 0, k = 0;
if (i2 == 0) {
while (n > 0 && arr1[0] <= arr2[0]) {
arr1++;
n--;
}
}
if (chunk > n)
chunk = n;
for (k = 0; k < chunk; k++)
tmp[k] = arr1[k];
if (chunk <= i2) {
for (j = 0; j < chunk; j++)
arr1[j] = arr2[j];
for (k = 0; j < i2; k++)
arr2[k] = arr2[j++];
} else {
for (k = 0; j < i2; k++)
arr1[k] = arr2[j++];
for (; k < chunk; k++) {
if (j >= m || tmp[i] <= arr2[j])
arr1[k] = tmp[i++];
else
arr1[k] = arr2[j++];
}
k = 0;
}
for (; i < chunk; k++) {
if (j >= m || tmp[i] <= arr2[j])
arr2[k] = tmp[i++];
else
arr2[k] = arr2[j++];
}
i2 = k;
}
}
Reducing the temporary storage size slows down execution time almost linearly: merge_chrlie2 is still 100x faster than the posted code with a local array of 12 elements, which can hardly be considered extra storage.
I ran a benchmark in C, using the no space merge function as the merge phase of a classic top down recursive merge sort. Here are the timings(*) with a temporary array of 128 elements:
size malloc chqrlie3 chqrlie2 chqrlie shivam
1000 0.059 0.064 0.064 0.252 2.010
2000 0.153 0.124 0.126 0.836 7.872
5000 0.441 0.505 0.528 5.218 49.947
10000 0.667 0.769 0.898 19.850 205.316
20000 1.531 1.917 2.195 85.185 812.061
50000 4.036 6.123 9.244 524.873 5197.808
100000 8.281 15.466 28.787 2064.165 20485.584
200000 18.030 51.438 106.391 8342.140 82226.825
500000 49.201 246.224 557.470 51982.830 511418.600
1000000 112.594 915.575 2171.953 207096.552 2053797.858
2000000 215.045 3883.104 8476.783 829806.868 8153974.589
5000000 565.701 34142.299 67304.217 5855744.544 51565024.699
And here are the timings with a temporary array of just 5 elements:
size malloc chqrlie3 chqrlie2 chqrlie shivam
1000 0.055 0.089 0.111 0.230 1.963
2000 0.165 0.247 0.327 0.880 7.891
5000 0.438 1.309 1.914 4.971 50.376
10000 0.799 2.832 5.675 21.544 202.929
20000 1.589 9.265 23.528 82.582 826.768
50000 4.150 53.408 131.302 519.007 5089.592
100000 8.375 205.644 533.308 2016.670 20431.584
200000 17.291 797.865 2193.575 9536.996 82308.875
500000 61.955 6565.826 15626.427 50813.910 508269.938
1000000 105.836 21146.977 52530.060 205640.244 2036022.030
(*) timings in milliseconds, extrapolated for chqrlie and shivam for arrays larger than 50k and 200k respectively.
Since you can't use any extra space, you can implement a kind of selection sort of both these arrays at once n + m, checking each index along the way, whether it is already in the second array, or not:
public static void main(String[] args) {
int[] arr1 = {1, 3, 5, 7};
int[] arr2 = {0, 2, 6, 8, 9};
selectionSort(arr1, arr2);
System.out.println(Arrays.toString(arr1)); // [0, 1, 2, 3]
System.out.println(Arrays.toString(arr2)); // [5, 6, 7, 8, 9]
}
public static void selectionSort(int[] arr1, int[] arr2) {
int n = arr1.length;
int m = arr2.length;
for (int i = 0; i < n + m; i++) {
int min = i < n ? arr1[i] : arr2[i - n];
int min_i = i;
for (int j = i + 1; j < n + m; j++)
if (j < n ? arr1[j] < min : arr2[j - n] < min) {
min = j < n ? arr1[j] : arr2[j - n];
min_i = j;
}
if (i != min_i)
if (i < n) {
int temp = arr1[i];
if (min_i < n) {
arr1[i] = arr1[min_i];
arr1[min_i] = temp;
} else {
arr1[i] = arr2[min_i - n];
arr2[min_i - n] = temp;
}
} else {
int temp = arr2[i - n];
if (min_i < n) {
arr2[i - n] = arr1[min_i];
arr1[min_i] = temp;
} else {
arr2[i - n] = arr2[min_i - n];
arr2[min_i - n] = temp;
}
}
}
}
See also: Java Selection Sort

How to find the maximum subarray of size >= 2 for the given array?

Given an array and an integer k, find the maximum for each and every contiguous subarray of size >=2.
INPUT:
int[] array = new int[]{-5,-2,-3,-1,-1};
int[] array1 = new int[]{5,2,3,-3,1,1};
OUTPUT:
-1,-1 //Since the maximum sum with maximum contiguous subarray can be of size 2 or greater than 2 and all are negative, so we taking the subarray = -1 -1
5,2,3 // Because we need to find the maximum sum and maximum subarray with limitation that array can be >= 2
I have solved this but my solution is not working when all the integers are negative. Also, it is not working when input is -5,-2,-3,-3,1,1. The output should be 1 and 1 but it is coming as -3,-3,1 and 1.
I need an optimized solution. Please find my code below:
public class Pro {
static int[] maxSubarray(int[] a) {
int max_sum = a[0];
int curr_sum = a[0];
int max_start_index = 0;
int startIndex = 0;
int max_end_index = 1;
for (int i = 1; i < a.length; i++) {
if (max_sum > curr_sum + a[i]) {
startIndex = i-1;
curr_sum = a[i];
} else {
curr_sum += a[i];
}
if (curr_sum > max_sum) {
max_sum = curr_sum;
max_start_index = startIndex;
max_end_index = i;
}
}
if (max_start_index <= max_end_index) {
return Arrays.copyOfRange(a, max_start_index, max_end_index + 1);
}
return null;
}
public static void main(String[] args) {
int[] array = new int[]{-5,-2,-3,-1,-1};
int[] array1 = new int[]{5,2,-3,1,1};
int[] out = maxSubarray(array1);
for(int a : out)
{
System.out.println(a);
}
}
}
There is one more code snippet which can be helpful. It finds the maximum subarray. See code below:
public int maxSubArray(int[] A) {
int max = A[0];
int[] sum = new int[A.length];
sum[0] = A[0];
for (int i = 1; i < A.length; i++) {
sum[i] = Math.max(A[i], sum[i - 1] + A[i]);
max = Math.max(max, sum[i]);
}
return max;
}
The algorithm you are using is called Kardane's algorith and cannot be used when all the numbers are negative. At least one number has to be positive for the algorithm to work. To make it work for arrays with negative numbers but also at least one positive number, curr_sum should be set to 0 whenever you come across a negative number in your array. One way to achieve this is to use a custom max-function
private int max(int first, int second) {
if (first < second) return first;
else return second;
}
Replace:
if (max_sum > curr_sum + a[i]) {
startIndex = i-1;
curr_sum = a[i];
} else {
curr_sum += a[i];
}
with:
curr_sum = max(curr_sum + a[i], 0);
if (curr_sum == 0) startIndex = i + 1;
Full code:
public int max(int[] a) {
int max_sum = a[0];
int curr_sum = a[0];
int startIndex = 0;
int max_start_index = 0;
int max_end_index = 1;
for (int i = 1; i < a.length; i++) {
max_sum = max(max_sum + a[i], 0);
if (max_sum == 0) startIndex = i + 1;
curr_sum = max(curr_sum, max_sum);
if (curr_sum == max_sum) {
max_start_index = startIndex;
max_end_index = i;
}
}
System.out.println("Start index: " + max_start_index);
System.out.println("End index: " + max_end_index);
return curr_sum;
}
Input: -5, -2, -3, -3, 1, 1
Output:
Start index: 4
End index: 5
2

How to find number of tuples whose sum is equal or less than a given number?

I'm designing an algorithm to find the number of tuples whose sum is equal or less than a given number. I know other ways of solving it using LinkedList, so, not looking for that solution. I just want to traverse through the array and count the possible matches that satisfy the relation. I come up so far,
public static int numberOfPairs(int[] a, int k ){
int len = a.length;
if (len == 0){
return -1;
}
Arrays.sort(a);
int count = 0, left = 0, right = len -1;
while( left < right ){
if ( a[left] + a[right] <= k ){
// System.out.println(a[left] + "\t" + a[right]);
count++;
/*may be the same numbers will also satisfy the relation*/
if ( a[left] + a[left+1] <= k) {
count ++;
// System.out.println(a[left] + "\t"+a[left+1]);
}
/*now, use iteration to traverse the same elements*/
while (a[left] == a[left+1] && left < len-1 ){
left++;
}
/*may be the same numbers will also satisfy the relation*/
if ( a[right] + a[right-1] <= k) {
count ++;
// System.out.println(a[right] +"\t"+ a[right-1]);
}
/*now, use iteration to traverse
the same elements*/
while ( a[right] == a[right-1] && right >1 ){
right-- ;
}
}
// traverse through the array
left++;
right--;
}
return count;
}
This is not providing the correct solution, say, if I pass array and number as following,
int [] arr = { 3, 3, -1, 4, 2,5, 5, 1};
System.out.println(numberOfPairs(arr, 8));
The correct solution will be 15 pairs as following,
{
{-1,1}, {-1,2} , {3,-1}, {-1,4 }, {-1,5},
{2,1},{3,1 },{4,1}, { 5,1},
{3,2 },{4,2}, {2,5 },
{3,4 } , {3,5 },
{3,3}
}
How can I improve my code ? thanks.
Note: the other way I solve it using LinkedList is as following,
public static int numberOfPairs10(int[] arr, int sum){
/*1.can be the same values of i
2. can be the same valus of j for the same i*/
List<Integer> li = new ArrayList<Integer>();
List<Integer> lj;
int count = 0;
for ( int i =0; i < arr.length -1 ; i++){
if (li.contains(arr[i]) )
continue;
lj = new ArrayList<Integer>();
for (int j = i+1; j < arr.length; j++){
if (lj.contains(arr[j]))
continue;
// if ( arr[i]+ arr[j] <= sum){
if ( arr[i]+ arr[j] == sum){
count++;
lj.add(arr[j]);
}
}
li.add(arr[i]);
}
return count;
}
This is tested with just
int [] arr = { 3, 3, -1, 4, 2,5, 5, 1};
numberOfPairs(arr, 8);
and here is codes
public static int numberOfPairs(int[] a, int k ) {
int len = a.length;
int counter = 0;
boolean isCheckedLeft = false;
boolean isCheckedRight = false;
int i, j, h;
Arrays.sort(a);
for (i = 0; i < len; i++) {
isCheckedLeft = false;
for (j = i - 1; j >= 0; j--) {
if (a[i] == a[j]) {
isCheckedLeft = true;
break;
}
}
if (isCheckedLeft) {
continue;
}
for (j = i + 1; j < len; j++) {
isCheckedRight = false;
for (h = j - 1; h > i; h--) {
if (a[j] == a[h]) {
isCheckedRight = true;
break;
}
}
if (isCheckedRight) {
continue;
}
System.out.print("("+a[i]+", "+a[j]+") ");
if (a[i] + a[j] <= k) {
counter++;
}
}
}
return counter;
}
If you are not too worried about performance then you could just find all unique combinations and then filter according to your condition. For example, using Java 8 streams:
public int numberOfPairs(int[] values, int maxVal) {
return IntStream.range(0, values.length)
.flatMap(i1 -> IntStream.range(i1 + 1, values.length)
.map(i2 -> Arrays.asList(values[i1], values[i2])))
.distinct().filter(l -> l.stream().sum() <= maxVal).count();
}

Return 0 or 1 from a method depending upon values in an array

I am a beginner. I am unable to figure out how to write a function which will return 1, if have this property:
arr[0] = arr[1] + arr[2] = arr[3] + arr[4] + arr[5] = arr[6] + arr[7] + arr[8] + arr[9] = ...
else returns 0. The length of an array must be n*(n+1)/2 for some n.
For example, if input array is {2, 1, 1, 4, -1, -1}, it returns 1 because 2 = 1 + 1, 2 = 4 + -1 + -1
I have tried this:
public static int myArray(int[] a) {
int len = a.length;
if (checkLenght(len)) {
int firstElem = a[0];
int value = 1;
int sum = 0;
for (int i = 1; i <= a.length; i++) {
for (int j = value; j < value + 1; j++) {
sum += a[j];
value++;
}
}
}
return 0;
}
public static boolean checkLenght(int len) {
for (int i = 0; i <= 100; i++) {
if ((i * (i + 1) / 2) == len) {
return true;
}
}
return false;
}
Thanks in advance.
I try to partition input in sets of two , three , .... elements. for that I use a pointer to show how many elements are in this partition. firs it is 2. then it is three , ... . and I use a temp number to count if in this partition I have enough element or not. after I have enough element in each partition I just check sum of the element of that partition.
This should do the work:
public static int myArray(int[] a) {
int len = a.length;
if (checkLenght(len)) {
int firstElem = a[0];
int pointer = 2; // pointer that will be 2, 3, 4 , ...
int sum = 0; // sum of element in each partition
int temp = 0; // a temp value to check if I reach desirable number of element in this partition or not.
for (int i = 1; i < a.length; i++) { // i<=a.length give you exception.
temp++;
sum += a[i];
if (temp == pointer) { // check if I have enough element.
pointer++; // plus pointer by one
temp = 0; // reset temp
if (sum != firstElem) // if in any of those partitions my needs doesnt meet I return zero.
return 0;
sum = 0; // reset sum
}
}
return 1;
}
return 0;
}

Find out the odd value and meet criteria in java

I would like to write a function in java that receives a parameter and returns 1 or 0, in the following conditions:
If the length of the array is odd, return 1 if the sum of the odd numbers is greater than the sum of the even numbers, and 0 otherwise.
If the length of the array is even, check the largest number less or equal then 10. If it is odd, return 1. If it is even, return 0.
For example, using the following arrays:
array1 = {13, 4, 7, 2, 8}
array2 = {11, 7, 4, 2, 3, 10}
The first array returns 1, because there 13(odd) + 7(odd) = 20 is greater then 4 + 2 + 8 = 14.
The second array returns 0, because there 11, 7 are odd but, 10 is greater then 7.
What I already tried, please check below:
public static int isOddHeavy(int[] arr) {
int summationOd = 0;
int summationEv = 0;
for (int i = 0; i < arr.length; i++) {
if (i % 2 != 0) {
summationOd = sumOddEven(arr);
} else {
summationEv = sumOddEven(arr);
}
}
if(summationOd > summationEv) {
return 1;
} else {
return 0;
}
}
public static int sumOddEven(int[] arr) {
int total = 0;
for (int i = 1; i < arr.length; i++) {
total += arr[i];
}
return total;
}
Here is a Java function that does what you want. Just iterate through the array, updating the variables and check your conditions in the end.
public static int yourFunction(int[] arr) {
int sumOdd = 0;
int sumEven = 0;
int maxOdd = 0;
int maxEven = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
sumEven += arr[i];
if (maxEven < arr[i] && arr[i] <= 10)
maxEven = arr[i];
}
else {
sumOdd += arr[i];
if (maxOdd < arr[i] && arr[i] <= 10)
maxOdd = arr[i];
}
}
if (arr.length%2 != 0)
return (sumOdd > sumEven) ? 1 : 0;
return (maxOdd > maxEven) ? 1 : 0;
}

Categories