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
Related
public class array12 {
static void merge_sort(int A[], int start, int end) {
if (end - start > 1) {
int middle1 = (2 * start + end + 1) / 3 - 1;
int middle2 = 2 * middle1 - start + 1;
merge_sort(A, start, middle1);
merge_sort(A, middle1 + 1, middle2);
merge_sort(A, middle2 + 1, end);
merge(A, start, middle1, middle2, end);
}
}
static void merge(int[] x, int start, int middle1, int middle2, int end) {
int n1 = middle1 - start + 1;
int n2 = middle2 - middle1;
int n3 = end - middle2;
int left[] = new int[n1]; // defining and initialising three arrays .
int mid[] = new int[n2];
int right[] = new int[n3];
for (int i = 0; i < left.length; i++) {
left[i] = x[i + start];
}
for (int i = 0; i < mid.length; i++) {
mid[i] = x[i + middle1 + 1];
}
for (int i = 0; i < right.length; i++) {
right[i] = x[i + middle2 + 1];
}
int i = 0;
int j = 0;
int k = 0;
int c = start;
// finding minimum element from the three arrays .
while (i < n1 && j < n2 && k < n3) {
if (left[i] <= mid[j] && left[i] <= right[k]) {
x[c] = left[i];
i++;
c++;
} else if (mid[j] <= left[i] && mid[j] <= right[k]) {
x[c] = mid[j];
j++;
c++;
} else {
x[c] = right[k];
k++;
c++;
}
}
// now only two arrays are left to be compared
while (i < n1 && j < n2) {
if (left[i] <= mid[j]) {
x[c] = left[i];
i++;
c++;
} else {
x[c] = mid[j];
j++;
c++;
}
}
while (j < n2 && k < n3) {
if (mid[j] <= right[k]) {
x[c] = mid[j];
j++;
c++;
} else {
x[c] = right[k];
k++;
c++;
}
}
while (i < n1 && k < n3) {
if (left[i] <= right[k]) {
x[c] = left[i];
i++;
c++;
} else {
x[c] = right[k];
k++;
c++;
}
}
// now only single array is left out of left[] , mid[] and right[].
while (i < n1) {
x[c] = left[i];
i++;
c++;
}
while (j < n2) {
x[c] = mid[j];
j++;
c++;
}
while (k < n3) {
x[c] = right[k];
k++;
c++;
}
System.out.println("");
// printing array elements after every merge operation .
for (int e = 0; e < x.length; e++) {
System.out.print(x[e] + " ");
}
}
public static void main(String[] args) {
int[] x = new int[9];
for (int i = 0; i < x.length; i++) {
x[i] = x.length - i;
}
System.out.println("initial array is : ");
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
System.out.println("");
merge_sort(x, 0, x.length - 1);
System.out.println("");
System.out.println("");
System.out.println(" sorted array is : ");
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
}
}
I am trying to merge 3 sorted arrays . I have been able to develop code for array size equal to power of 3 . I am unable to implement it with some other array size . I have tried to change values of middle1 and middle2 but am experiencing serious trouble . Setting their values is the main concern . Merging step is quite simple and is not causing problems .
What changes are required in my code so that it may work for any array size ? Can it be implemented using this approach ? I dont want size of any of the three arrays , left[] , mid[] and right[] to be zero at any time .
Please help .
Here's a similar answer to YCF_L's, but simplified (still uses Java 8):
public static int[] sortMultipleArrays(int[]... arrays) {
return Arrays.stream(arrays)
.flatMapToInt(Arrays::stream)
.sorted()
.toArray();
}
Output:
[1, 2, 3, 5, 6, 7, 9, 10, 12, 13, 17, 20, 21, 24]
I don't follow your merge code. It seems overly complicated.
Here is a method for merging an unlimited number of sorted arrays, each a varying size.
private static int[] mergeSortedArrays(int[]... arrays) {
int totalLen = 0;
for (int[] arr : arrays)
totalLen += arr.length;
int[] idx = new int[arrays.length];
int[] merged = new int[totalLen];
for (int i = 0; i < totalLen; i++) {
int min = 0, minJ = -1;
for (int j = 0; j < arrays.length; j++)
if (idx[j] < arrays[j].length)
if (minJ == -1 || min > arrays[j][idx[j]]) {
min = arrays[j][idx[j]];
minJ = j;
}
merged[i] = min;
idx[minJ]++;
}
return merged;
}
Test
int[] a = { 3, 5, 9, 13, 17, 21 };
int[] b = { 2, 10, 20 };
int[] c = { 1, 7, 12, 24 };
int[] d = { 6 };
int[] merged = mergeSortedArrays(a, b, c, d);
System.out.println(Arrays.toString(merged));
Output
[1, 2, 3, 5, 6, 7, 9, 10, 12, 13, 17, 20, 21, 24]
If using class "Integer" instead of primitive int is not a problem you can use this, basically first do the merge and after sort them: you can do the call Arrays.sort even in the same method and call it mergeAndSort, if you want...
import java.util.Arrays;
public class Main {
public static Integer[] merge(Integer[]... arrays) {
int count = 0;
for (Integer[] array : arrays) {
count += array.length;
}
Integer[] mergedArray = (Integer[]) java.lang.reflect.Array.newInstance(arrays[0][0].getClass(), count);
int start = 0;
for (Integer[] array : arrays) {
System.arraycopy(array, 0, mergedArray, start, array.length);
start += array.length;
}
return mergedArray;
}
public static void main(String[] args) {
Integer[] array1 = {3, 5, 6, 7, 78, 100};
Integer[] array2 = {5, 6, 7, 8, 9};
Integer[] array3 = {2, 6, 7};
Integer[] merged1 = merge(array1, array2);
Arrays.sort(merged1);
Integer[] merged2 = merge(array1, array2, array3);
Arrays.sort(merged2);
printArray(merged1);
printArray(merged2);
}
public static void printArray(Integer[] x) {
System.out.println("--ToString--");
for (Integer var : x) {
System.out.println(var);
}
System.out.println("----");
}
}
I want to generate a matrix with consecutive numbers starting from 1, in this form
zig zag matrix
public static int[][] Zig_Zag(final int size) {
int[][] data = new int[size][size];
int i = 1;
int j = 1;
for (int element = 0; element < size * size; element++) {
data[i - 1][j - 1] = element;
if ((i + j) % 2 == 0) { // Even stripes if (j < size) j++; else i+=
// 2; if (i > 1) i--; } else { // Odd
// stripes if (i < size) i++; else j+= 2; if
// (j > 1) j--; } } return data; }
}
}
return data;
}
Can anybody help?
Try this
public static int[][] Zig_Zag(int size) {
int[][] a = new int[size][size];
int n = 1;
for (int r = size, c = 0; r >= 0; --r)
for (int i = r, j = c; i < size; ++i, ++j)
a[i][j] = n++;
for (int r = 0, c = 1; c < size; ++c)
for (int i = r, j = c; j < size; ++i, ++j)
a[i][j] = n++;
return a;
}
and
int[][] a = Zig_Zag(4);
for (int[] r : a)
System.out.println(Arrays.toString(r));
result:
[7, 11, 14, 16]
[4, 8, 12, 15]
[2, 5, 9, 13]
[1, 3, 6, 10]
Try this code :
public static int[][] Zig_Zag(final int size) {
int[][] data = new int[size][size];
int i = 1;
int j = 1;
for (int element = 1; element <= size * size; element++) {
data[i - 1][j - 1] = element;
if ((i + j) % 2 == 0) {
// Even stripes
if (j < size)
j++;
else
i += 2;
if (i > 1)
i--;
} else {
// Odd stripes
if (i < size)
i++;
else
j += 2;
if (j > 1)
j--;
}
}
return data;
}
public static void main(String[] args) {
int[][] data = Zig_Zag(4);
for(int i=0; i<data.length;i++){
for(int j=0; j<data[i].length;j++){
System.out.print(data[i][j]+" ");
}
System.out.println("");
}
}
Output:
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
Not a very elegant solution:
private static int triangle_below(int n) {
return n * (n + 1) / 2;
}
private static int except_triangle_above(int size, int n) {
return size * size - triangle_below(2 * size - n);
}
private static int[][] gen(int size) {
int[][] m = new int[size][size];
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
// already filled cells in lower diagonal layers
int k = Math.min(
triangle_below(i + j),
except_triangle_above(size, Math.max(size, i + j + 1))
);
// position in current layer
int l = Math.min(j + 1, size - i);
m[size - i - 1][j] = k + l;
}
}
return m;
}
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));
}
}
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;
}
Can anyone give me example about shell sort? I'm a new person in here who must learn about shell sort, but first I must find a Java shell sort example. I found one example in Google but it's too difficult.
Here, this code is very simple :
/**
* Shellsort, using Shell’s (poor) increments.
* #param a an array of Comparable items.
*/
public static <T extends Comparable<? super T>>
void shellsort( T [ ] a )
{
int j;
for( int gap = a.length / 2; gap > 0; gap /= 2 )
{
for( int i = gap; i < a.length; i++ )
{
T tmp = a[ i ];
for( j = i; j >= gap && tmp.compareTo( a[ j - gap ] ) < 0; j -= gap )
{
a[ j ] = a[ j - gap ];
}
a[ j ] = tmp;
}
}
}
I stole it from a book called Data Structures and Algorithm Analysis in Java. It is very good book easy to understand. I advise you to read it.
May be, this java code will help you.
public class ShellSort {
private long[] data;
private int len;
public ShellSort(int max) {
data = new long[max];
len = 0;
}
public void insert(long value){
data[len] = value;
len++;
}
public void display() {
System.out.print("Data:");
for (int j = 0; j < len; j++)
System.out.print(data[j] + " ");
System.out.println("");
}
public void shellSort() {
int inner, outer;
long temp;
//find initial value of h
int h = 1;
while (h <= len / 3)
h = h * 3 + 1; // (1, 4, 13, 40, 121, ...)
while (h > 0) // decreasing h, until h=1
{
// h-sort the file
for (outer = h; outer < len; outer++) {
temp = data[outer];
inner = outer;
// one subpass (eg 0, 4, 8)
while (inner > h - 1 && data[inner - h] >= temp) {
data[inner] = data[inner - h];
inner -= h;
}
data[inner] = temp;
}
h = (h - 1) / 3; // decrease h
}
}
public static void main(String[] args) {
int maxSize = 10;
ShellSort arr = new ShellSort(maxSize);
for (int j = 0; j < maxSize; j++) {
long n = (int) (java.lang.Math.random() * 99);
arr.insert(n);
}
arr.display();
arr.shellSort();
arr.display();
}
}
Shell sort improves insertion sort by comparing elements separated by a gap of several positions.
This lets an element take "bigger steps" toward its expected position. Multiple passes over the data are taken with smaller and smaller gap sizes. The last step of Shell sort is a plain insertion sort, but by then, the array of data is guaranteed to be almost sorted.
This code might help you in understanding the logic better.
package Sorts;
public class ShellSort extends Sorter{
#Override
public <T extends Comparable<? super T>> void sort(T[] a) {
int h = 1;
while((h*3+1) < a.length)
h = 3*h+1;
while(h > 0){
for(int i = h-1; i < a.length; i++){
T s = a[i];
int j = i;
for(j = i; (j>=h) && (a[j-h].compareTo(s) > 0); j-=h)
a[j] = a[j-h];
a[j] = s;
}
h /= 3;
}
}
}
Here is a visualization of shell sort for a python implementation:
def exch(a,i,j):
t = a[i]
a[i] = a[j]
a[j] = t
def shellsort(string):
print string
a = list(string)
N = len(a)
h = 1
i = 0
j = 0
k = 0
#determine starting stride length
while ( h < N/3 ):
h = 3*h + 1
print "STRIDE LENGTH: " + str(h)
while (h >=1):
i = h
while i < N:
j = i
k = j - h
while j >= h and a[j] < a[j-h]:
k = j - h
exch(a,j,k)
j -= h
i += 1
h = h/3
print "STRIDE LENGTH: " + str(h)
print ''.join(a)·
if __name__ == '__main__':
shellsort("astringtosortwithshellsort")
Here's an example:
public static void shellsort( Comparable [ ] a )
{
for( int gap = a.length / 2; gap > 0;
gap = gap == 2 ? 1 : (int) ( gap / 2.2 ) )
for( int i = gap; i < a.length; i++ )
{
Comparable tmp = a[ i ];
int j = i;
for( ; j >= gap && tmp.compareTo( a[ j - gap ] ) < 0; j -= gap )
a[ j ] = a[ j - gap ];
a[ j ] = tmp;
}
}
I find the easiest way to understand shell sort is to break it down into segments:
private static void shellsort() {
int[] theArray = {44,5,33,22,765,43,53,12,57,97};
//first section gets the Knuth's interval sequence (very efficient)
int h=1;
while(h<= theArray.length/3){
h = 3*h + 1; //h is equal to highest sequence of h<=length/3 (1,4,13,40...)
}
//next section
while(h>0){ //for array of length 10, h=4
//similar to insertion sort below
for(int i=0; i<theArray.length; i++){
int temp = theArray[i];
int j;
for(j=i; j>h-1 && theArray[j-h] >= temp; j=j-h){
a[j] = a[j-h];
}
a[j] = temp;
}
h = (h-1)/3;
}
}
Output: 5, 12, 22, 33, 43, 44, 53, 57, 97, 765
Classic primitive type implementation:
package math;
import java.util.Arrays;
public class Sorter{
public static void main(String []args){
int[] a = {9,8,7,6,5,4,3,2,1};//plz use sophisticated random number generator
System.out.println( Arrays.toString(a) );
System.out.println( Arrays.toString(shellSort(a)) );
}
//Performs a shell sort on an array of ints.
public static int[] shellSort(int[] array){
int h = 1;
while (h < array.length) h = 3*h + 1;
while (h > 0){
h = h/3;
for (int k = 0; k < h; k++){
for (int i = h+k; i < array.length; i+=h){
int key = array[i];
int j = i-h;
while (j>=0 && array[j] > key){
array[j+h] = array[j];
j-=h;
}
array[j+h] = key;
//-> invariant: array[0,h,2*h..j] is sorted
}
}
//->invariant: each h-sub-array is sorted
}
return array;
};
}
P.S.: Check this link for other sorting algorithms (they are in c++, though, easily portable to java).
package sort_tester;
public class ShellSorter extends Sorter {
private final int[] gapArray = {1750,701,301,132,57,23,10,4,1};
#Override
public void makeSort (boolean trace) {
int size = list.length;
int i,j, temp;
for ( int gap : gapArray ) {
i = gap;
while ( i < size ) {
temp = list[i];
j = i-gap;
while ( j >= 0 && list[j] > temp ) {
list[j + gap] = list[j];
j -= gap;
}
list[j + gap] = temp;
i ++;
}
}
}
}
list - is int[];
GapArray taken from arcticle of Marcin Ciura
http://sun.aei.polsl.pl/~mciura/publikacje/shellsort.pdf
Here is a video link: https://youtu.be/SCBf7aqKQEY
The guy has made a good video of shell sort!!
And a simple code:
int sort(int arr[])
{
int n = arr.length;
int gap = n/2;
int i,j;
while(gap>0)
{ for (i=0,j=i+gap; j<n; i++,++j)
{
if(arr[i]>arr[j]) //swap
{ int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
gap=gap/2;
}
return 0;
}
Use this
public void shellSort(Integer[] arr) {
int interval = arr.length / 2;
while (interval != 0) {
for (int i = 0; i < interval; i++) {
for (int p = i + interval; p < arr.length; p += interval) {
int key = arr[p];
int j = p - interval;
while (j >= 0) {
if (key < arr[j]) {
arr[j + interval] = arr[j];
} else
break;
j -= interval;
}
arr[j + interval] = key;
}
}
interval /= 2;
}
}
Snippet with 3k+1 gap.
public void shellSort(Comparable arr[], int size, int h, int x) {
while (h >= 1) {
for (int i = 0; i <= size - h; i++) {
for (int j = i; j < size-h && (arr[j].compareTo(arr[j+h]) > 0); j += h)
swap(arr, j, j+h);
}
h = 3*(--x) + 1;
}
}