I had an exam which I failed to display it.
Kindly help how to achieve this
Given an array A[] of size N and an integer k. Task is to print the minimum element for each subarray of size k.
For Each valid index i(0<=i <=N -K) Have to print min(A[i],A[i+1],A[i+2]...A[i+k]).
Input format:
The first line will coontains two integers N and k.
The second line contain N intgers denoting the elements of Array A[]
Constraints:
1 <=N <=10^5
1<=K <= N
1<=A[i] <=10^6
Output Format
print the minimum elements for each subarray of size k separated by space.
input:
5 2
10 0 3 2 5
output:
0 0 2 2
But what I tried is find maximum element:
I know this is wrong. But I know only this.
public static int maxSum(int arr[], int n, int k)
{
// k must be greater
if (n < k)
{
System.out.println("Invalid");
return -1;
}
// Compute sum of first window of size k
int res = 0;
for (int i=0; i<k; i++)
res += arr[i];
// Compute sums of remaining windows by
// removing first element of previous
// window and adding last element of
// current window.
int curr_sum = res;
for (int i=k; i<n; i++)
{
curr_sum += arr[i] - arr[i-k];
res = Math.max(res, curr_sum);
}
return res;
}
/* Driver program to test above function */
public static void main(String[] args)
{
int arr[] = {5,2,10,0,3,2,5};
int k = 7;
int n = arr.length;
System.out.println(maxSum(arr, n, k));
}
}
This is a super-straightforward solution I wrote in about 5 minutes.
Note I don't perform the input, the n, k, array values are just hardcoded in main method.
package stackoverflow;
public class MinimumSubArray {
public static void main(String[] args) {
solve(5, 2, new int[]{ 10, 0, 3, 2, 5 }); // expect 0 0 2 2
solve(5, 2, new int[]{ 10, 0, 3, 2, 1 }); // expect 0 0 2 1
solve(1, 1, new int[]{ 6 }); // expect 6
solve(3, 3, new int[]{ 3, 2, 1 }); // expect 1
solve(3, 1, new int[]{ 3, 2, 1 }); // expect 3 2 1
}
private static void solve(final int n, final int k, final int[] array) {
if (n != array.length)
throw new IllegalArgumentException( String.format("Array length must be %d.", n) );
if (k > n)
throw new IllegalArgumentException( String.format("K = %d is bigger than n = %d.", k, n) );
int currentStartIndex = 0;
while (currentStartIndex <= (n - k)) {
int min = array[currentStartIndex];
for (int i = currentStartIndex + 1; i < currentStartIndex + k; i++) {
if (array[i] < min) {
min = array[i];
}
}
System.out.printf("%d ", min); // print minimum of the current sub-array
currentStartIndex++;
}
System.out.println();
}
}
Related
I am trying to find the subsets of an array. In example if the array is [1,2] I am trying to print the following:
[1][2]
[1]
[2]
null
The code that I have written is as follows:
import java.util.*;
class PrintArray {
public static void printme(int a[], int pos, int size) {
if (pos >= size)
return;
else
System.out.println(a[pos]);
pos++;
printme(a, pos, size);
}
public static void generate(int a[], ArrayList<Integer> list, int pos, int size) {
if (pos > size) {
for (int i = 0; i < list.size() - 1; i++) {
System.out.print("[" + list.get(i) + "]");
}
System.out.println();
return;
}
list.add(a[pos]);
generate(a, list, pos + 1, size);
list.remove(list.size() - 1);
generate(a, list, pos + 1, size);
}
public static void main(String args[]) {
int ar[] = { 1, 2, 3, 4, 5 };
// printme(ar, 0, ar.length);
ArrayList<Integer> list = new ArrayList<Integer>();
generate(ar, list, 0, ar.length);
}
}
However I am running into the following OOBE error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds
That can be resolved by checking for pos>=size instead of pos>size but such a change does not generate all the sub-arrays.
A follow-up problem is that I am getting duplicate outputs as shown below:
[2][3][4]
[2][3]
[2][3]
[2]
[2][4]
[2]
[2]
Could someone please help me in overcoming these 2 issues?
You can look at your subsets array as a matrix. For {x, y} array:
the matrix will have 2^n elements, where n is the number of elements in the array;
it can be visualized in binary, 1 means print the element and 0 doesn't print anything:
public static void main (String[] args) throws Exception
{
int ar[] = {1, 2};
int nrOfSubsets = (int) Math.pow (2, ar.length);
// prints the subset matrix
for (int i = nrOfSubsets - 1; i >= 0; i--)
{
String output = "";
int temp = i;
// prints one matrix line
for (int j = ar.length - 1; j >= 0; --j)
{
// convert to binary, 1 means print the number
int rem = temp % 2;
temp = temp / 2;
if (rem == 1)
{
output = "[" + ar[j] + "]" + output;
}
}
if(output.isEmpty()) output = "null";
System.out.println (output);
}
}
So, I have implemented the binomial coefficient
public static int binomial(int n, int k) {
if (k == 0)
return 1;
else if (k > n - k)
return binomial(n, n - k);
else
return binomial(n - 1, k - 1) * n / k;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Insert n: ");
int n = scan.nextInt();
System.out.println("Insert k: ");
int k = scan.nextInt();
System.out.println("Result: " + binomial(n, k));
}
And it works, but where I'm stuck is just that I need to add the coefficient array for two given numbers. So If n is 5 and k is 3. The coefficient array will display: 1 5 10 10. Any ideas?
Don't call recursive code in a for loop. That adds a stupid amount of redundancy.
Pass the array as a parameter to the recursive function from main. Arrays are passed by reference in java.
public static int binomial(int n, int k, int[] coefficient) {
int ret;
if (k == 0) {
ret = 1;
} else if (k > n - k) {
ret = binomial(n, n - k, coefficient);
} else {
ret = binomial(n - 1, k - 1, coefficient) * n / k;
}
coefficient[k] = ret;
return ret;
}
All you need to do is put your expression in a loop and hold n constant.
for (int k = 0; k <= n; k++) {
System.out.print(binomial(n, k) + " ");
}
You can store these values in an array if you like. There is no need to make your method any more complicated.
If want to put it in an array, here is one easy way to do it.
int coefs[] = IntStream.rangeClosed(0, n).map(k -> binomial(n, k)).toArray();
coefs[] = [1, 5, 10, 10, 5, 1]
You can create two iterative methods: one returns a 2d array containing Pascal's triangle, and the second returns the base of that triangle. It is more useful for clarity.
Output:
Insert n:
6
Pascal's triangle:
[1, 1, 1, 1, 1, 1]
[1, 2, 3, 4, 5]
[1, 3, 6, 10]
[1, 4, 10]
[1, 5]
[1]
Binomial coefficients:
[1, 5, 10, 10, 5, 1]
Code:
public static int[][] binomialTriangle(int n) {
// an array of 'n' rows
int[][] arr = new int[n][];
// iterate over the rows of the array
IntStream.range(0, n).forEach(i -> {
// a row of 'n-i' elements
arr[i] = new int[n - i];
// iterate over the columns of the array
IntStream.range(0, n - i).forEach(j -> {
if (i == 0 || j == 0)
// first row and column
// are filled with ones
arr[i][j] = 1;
else
// all other elements are the sum of the
// previous element in the row and column
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
});
});
return arr;
}
public static int[] binomialCoefficient(int[][] triangle) {
return Arrays.stream(triangle)
// the last element in the row
.mapToInt(row -> row[row.length - 1])
.toArray();
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Insert n:");
int n = scan.nextInt();
System.out.println("Pascal's triangle:");
int[][] arr = binomialTriangle(n);
Arrays.stream(arr).map(Arrays::toString).forEach(System.out::println);
int[] base = binomialCoefficient(arr);
System.out.println("Binomial coefficients:");
System.out.println(Arrays.toString(base));
}
See also: Convert negative index to positive index in an array (Trinomial Triangle)
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
import java.util.*;
class Main {
/* Utility function that puts all non-positive
(0 and negative) numbers on left side of
arr[] and return count of such numbers */
static int segregate(int arr[], int size)
{
int j = 0, i;
for (i = 0; i < size; i++) {
if (arr[i] <= 0) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// increment count of non-positive
// integers
j++;
}
}
return j;
}
/* Find the smallest positive missing
number in an array that contains
all positive integers */
static int findMissingPositive(int arr[], int size)
{
int i;
// Mark arr[i] as visited by making
// arr[arr[i] - 1] negative. Note that
// 1 is subtracted because index start
// from 0 and positive numbers start from 1
for (i = 0; i < size; i++) {
int x = Math.abs(arr[i]);
if (x - 1 < size && arr[x - 1] > 0)
arr[x - 1] = -arr[x - 1];
}
// Return the first index value at which
// is positive
for (i = 0; i < size; i++)
if (arr[i] > 0)
return i + 1; // 1 is added becuase indexes
// start from 0
return size + 1;
}
/* Find the smallest positive missing
number in an array that contains
both positive and negative integers */
static int findMissing(int arr[], int size)
{
// First separate positive and
// negative numbers
int shift = segregate(arr, size);
int arr2[] = new int[size - shift];
int j = 0;
for (int i = shift; i < size; i++) {
arr2[j] = arr[i];
j++;
}
// Shift the array and call
// findMissingPositive for
// positive part
return findMissingPositive(arr2, j);
}
// main function
public static void main(String[] args)
{
int arr[] = { 0, 10, 2, -10, -20 };
int arr_size = arr.length;
int missing = findMissing(arr, arr_size);
System.out.println("The smallest positive missing number is " + missing);
}
}
}
If you need to use stream, the more straightfoward, but not optimal way to do it is to create an infinite stream, starting at 1 and return the first that is not in arr:
int[] arr = { 1, 3, 6, 4, 1, 2 };
Set<Integer> arrSet = Arrays.stream(arr).boxed().collect(Collectors.toSet());
Optional<Integer> found = IntStream.iterate(1, o -> o + 1).boxed()
.filter(value -> !arrSet.contains(value))
.findFirst();
found.ifPresent(System.out::println);
Output
5
As pointed out this is very inefficient, but in terms of computational complexity I believe is optimal, at least for the worst case i.e. the one you have to look at all the elements.
Below you can find the missing positive integer using Streams -
int ar[] = { 0, 10, 2, -10, -20 };
int max = Arrays.stream(ar).max().getAsInt();
System.err.println("maxvalue "+max);
int val = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i))
.findFirst().getAsInt();
System.out.println(val);
int[] val1 = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(val1).forEach(System.out::println);
int[] valEven = IntStream.range(1, max).filter(i->Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven).forEach(System.out::println);
int[] valOdd = IntStream.range(1, max).filter(i->!Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd).forEach(System.out::println);
int[] valOdd1 = IntStream.range(1, max).filter(i->Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd1).forEach(System.out::println);
int[] valEven1 = IntStream.range(1, max).filter(i->!Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven1).forEach(System.out::println);
You can also do a mix of stream and primitive int loop:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numberSet1 = {1, 3, 6, 4, 1, 2};
int[] numberSet2 = {-1, -3};
int[] numberSet3 = {1, 2, 3};
System.out.println(calcularPrimero(numberSet1));
System.out.println(calcularPrimero(numberSet2));
System.out.println(calcularPrimero(numberSet3));
}
public static int calcularPrimero (int[] A) {
//IntStream intStream = Arrays.stream(A).filter(x -> x >= 0).distinct().sorted();
int[] B = Arrays.stream(A).filter(x -> x > 0).distinct().sorted().toArray();
for (int i = 0, index = 1; i < B.length; i++, index++) {
if (index != B[i]) {
return index;
}
}
return B.length + 1;
}
}
I have the following problem:
You are given N counters, initially set to 0, and you have two possible operations on them:
increase(X) − counter X is increased by 1,
max counter − all counters are set to the maximum value of any counter.
A non-empty zero-indexed array A of M integers is given. This array represents consecutive operations:
if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
if A[K] = N + 1 then operation K is max counter.
For example, given integer N = 5 and array A such that:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0)
(0, 0, 1, 1, 0)
(0, 0, 1, 2, 0)
(2, 2, 2, 2, 2)
(3, 2, 2, 2, 2)
(3, 2, 2, 3, 2)
(3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
Write a function:
class Solution { public int[] solution(int N, int[] A); }
that, given an integer N and a non-empty zero-indexed array A consisting of M integers, returns a sequence of integers representing the values of the counters.
For example, given:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the function should return [3, 2, 2, 4, 2], as explained above.
Assume that:
N and M are integers within the range [1..100,000];
each element of array A is an integer within the range [1..N + 1].
Complexity:
expected worst-case time complexity is O(N+M);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
I have answered this problem using the following code, but only got 80% as opposed to 100% performance, despite having O(N+M) time complexity:
public class Solution {
public int[] solution(int N, int[] A) {
int highestCounter = N;
int minimumValue = 0;
int lastMinimumValue = 0;
int [] answer = new int[N];
for (int i = 0; i < A.length; i++) {
int currentCounter = A[i];
int answerEquivalent = currentCounter -1;
if(currentCounter >0 && currentCounter<=highestCounter){
answer[answerEquivalent] = answer[answerEquivalent]+1;
if(answer[answerEquivalent] > minimumValue){
minimumValue = answer[answerEquivalent];
}
}
if (currentCounter == highestCounter +1 && lastMinimumValue!=minimumValue){
lastMinimumValue = minimumValue;
Arrays.fill(answer, minimumValue);
}
}
return answer;
}
}
Where is my performance here suffering? The code gives the right answer, but does not perform up-to-spec despite having the right time complexity.
Instead of calling Arrays.fill(answer, minimumValue); whenever you encounter a "max counter" operation, which takes O(N), you should keep track of the last max value that was assigned due to "max counter" operation, and update the entire array just one time, after all the operations are processed. This would take O(N+M).
I changed the variables names from min to max to make it less confusing.
public class Solution {
public int[] solution(int N, int[] A) {
int highestCounter = N;
int maxValue = 0;
int lastMaxValue = 0;
int [] answer = new int[N];
for (int i = 0; i < A.length; i++) {
int currentCounter = A[i];
int answerEquivalent = currentCounter -1;
if(currentCounter >0 && currentCounter<=highestCounter){
if (answer[answerEquivalent] < lastMaxValue)
answer[answerEquivalent] = lastMaxValue +1;
else
answer[answerEquivalent] = answer[answerEquivalent]+1;
if(answer[answerEquivalent] > maxValue){
maxValue = answer[answerEquivalent];
}
}
if (currentCounter == highestCounter +1){
lastMaxValue = maxValue;
}
}
// update all the counters smaller than lastMaxValue
for (int i = 0; i < answer.length; i++) {
if (answer[i] < lastMaxValue)
answer[i] = lastMaxValue;
}
return answer;
}
}
The following operation is O(n) time:
Arrays.fill(answer, minimumValue);
Now, if you are given a test case where the max counter operation is repeated often (say n/3 of the total operations) - you got yourself an O(n*m) algorithm (worst case analysis), and NOT O(n+m).
You can optimize it to be done in O(n+m) time, by using an algorithm that initializes an array in O(1) every time this operation happens.
This will reduce worst case time complexity from O(n*m) to O(n+m)1
(1)Theoretically, using the same idea, it can even be done in O(m) - regardless of the size of the number of counters, but the first allocation of the arrays takes O(n) time in java
This is a bit like #Eran's solution but encapsulates the functionality in an object. Essentially - keep track of a max value and an atLeast value and let the object's functionality do the rest.
private static class MaxCounter {
// Current set of values.
final int[] a;
// Keeps track of the current max value.
int currentMax = 0;
// Min value. If a[i] < atLeast the a[i] should appear as atLeast.
int atLeast = 0;
public MaxCounter(int n) {
this.a = new int[n];
}
// Perform the defined op.
public void op(int k) {
// Values are one-based.
k -= 1;
if (k < a.length) {
// Increment.
inc(k);
} else {
// Set max
max(k);
}
}
// Increment.
private void inc(int k) {
// Get new value.
int v = get(k) + 1;
// Keep track of current max.
if (v > currentMax) {
currentMax = v;
}
// Set new value.
a[k] = v;
}
private int get(int k) {
// Returns eithe a[k] or atLeast.
int v = a[k];
return v < atLeast ? atLeast : v;
}
private void max(int k) {
// Record new max.
atLeast = currentMax;
}
public int[] solution() {
// Give them the solution.
int[] solution = new int[a.length];
for (int i = 0; i < a.length; i++) {
solution[i] = get(i);
}
return solution;
}
#Override
public String toString() {
StringBuilder s = new StringBuilder("[");
for (int i = 0; i < a.length; i++) {
s.append(get(i));
if (i < a.length - 1) {
s.append(",");
}
}
return s.append("]").toString();
}
}
public void test() {
System.out.println("Hello");
int[] p = new int[]{3, 4, 4, 6, 1, 4, 4};
MaxCounter mc = new MaxCounter(5);
for (int i = 0; i < p.length; i++) {
mc.op(p[i]);
System.out.println(mc);
}
int[] mine = mc.solution();
System.out.println("Solution = " + Arrays.toString(mine));
}
My solution: 100\100
class Solution
{
public int maxCounterValue;
public int[] Counters;
public void Increase(int position)
{
position = position - 1;
Counters[position]++;
if (Counters[position] > maxCounterValue)
maxCounterValue = Counters[position];
}
public void SetMaxCounter()
{
for (int i = 0; i < Counters.Length; i++)
{
Counters[i] = maxCounterValue;
}
}
public int[] solution(int N, int[] A)
{
if (N < 1 || N > 100000) return null;
if (A.Length < 1) return null;
int nlusOne = N + 1;
Counters = new int[N];
int x;
for (int i = 0; i < A.Length; i++)
{
x = A[i];
if (x > 0 && x <= N)
{
Increase(x);
}
if (x == nlusOne && maxCounterValue > 0) // this used for all maxCounter values in array. Reduces addition loops
SetMaxCounter();
if (x > nlusOne)
return null;
}
return Counters;
}
}
( #molbdnilo : +1 !) As this is just an algorithm test, there's no sense getting too wordy about variables. "answerEquivalent" for a zero-based array index adjustment? Gimme a break ! Just answer[A[i] - 1] will do.
Test says to assume A values always lie between 1 and N+1. So checking for this is not needed.
fillArray(.) is an O(N) process which is within an O(M) process. This makes the whole code into an O(M*N) process when the max complexity desired is O(M+N).
The only way to achieve this is to only carry forward the current max value of the counters. This allows you to always save the correct max counter value when A[i] is N+1. The latter value is a sort of baseline value for all increments afterwards. After all A values are actioned, those counters which were never incremented via array entries can then be brought up to the all-counters baseline via a second for loop of complexity O(N).
Look at Eran's solution.
This is how we can eliminate O(N*M) complexity.
In this solutions, instead of populating result array for every A[K]=N+1, I tried to keep what is min value of all elements, and update result array once all operation has been completed.
If there is increase operation then updating that position :
if (counter[x - 1] < minVal) {
counter[x - 1] = minVal + 1;
} else {
counter[x - 1]++;
}
And keep track of minVal for each element of result array.
Here is complete solution:
public int[] solution(int N, int[] A) {
int minVal = -1;
int maxCount = -1;
int[] counter = new int[N];
for (int i = 0; i < A.length; i++) {
int x = A[i];
if (x > 0 && x <= N) {
if (counter[x - 1] < minVal) {
counter[x - 1] = minVal + 1;
} else {
counter[x - 1]++;
}
if (maxCount < counter[x - 1]) {
maxCount = counter[x - 1];
}
}
if (x == N + 1 && maxCount > 0) {
minVal = maxCount;
}
}
for (int i = 0; i < counter.length; i++) {
if (counter[i] < minVal) {
counter[i] = minVal;
}
}
return counter;
}
This is my swift 3 solution (100/100)
public func solution(_ N : Int, _ A : inout [Int]) -> [Int] {
var counters = Array(repeating: 0, count: N)
var _max = 0
var _min = 0
for i in A {
if counters.count >= i {
let temp = max(counters[i-1] + 1, _min + 1)
_max = max(temp, _max)
counters[i-1] = temp
} else {
_min = _max
}
}
return counters.map { max($0, _min) }
}
How can I do arrangements. of numbers... such that each new number formed out of arrangement has at max a difference of 1 from prev maxima.
e.g.
if input is k=1 output will be 1
if k =2 outputs are : 11, 12
2,1 is wrong as left most has to be 1 always.
if k = 3 outputs are: 111,112, 121, 122, 123
if k = 4 : 1111,1112,1121,1122,1123,1212,1211,1213,1223,1221, 1222, 1233, 1234
1423 is wrong diff b/w 1 and 4 is 3.
1243 is wrong diff b/w 2 and 4 is 2....
How I do this using DP, if possible?
This is one of the solution for above question... can anyone help me to understand this code...
Thanks in advance...
public class MaxOneDiff {
public static void main(String[] args) {
int k = 4;
getList(k);
}
public static void getList(int k) {
int arr[] = new int[k];
int index = 0;
printRecList(k, arr, index, k);
}
public static void printRecList(int k, int arr[], int index, int range) {
if (k == 0) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
} else {
for (int i = 1; i <= range; i++) {
if (index == 0) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
} else {
int t = arr[index-1]-i;
t = t > 0 ? t : -t;
if (t < 2) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
}
}
}
}
}
}
Let's start with the easy part:
public static void getList(int k) {
int arr[] = new int[k];
int index = 0;
printRecList(k, arr, index, k);
}
This is a helper to the Print Recursive List function, just setting up the initial stuff.
public static void printRecList(int k, int arr[], int index, int range) {
This is a recursive function, it should (and does) contain two main parts:
A base case (here, when k==0 )
A non-base case which does something, reducing the problem into smaller problem(s), and recurses.
Base case:
if (k == 0) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
If k==0, print out the numbers in the array from left to right, then put a new-line at the end.
Non-Base Case: (the more complicated part)
else {
for (int i = 1; i <= range; i++) {
if (index == 0) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
} else {
int t = arr[index-1]-i;
t = t > 0 ? t : -t;
if (t < 2) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
}
}
}
}
'i' goes from 1 to range,
The helper function calls this with index=0, so the first/top level of recursion, is composed of setting the first element (element 0) of the array to i, and calling the recursive method.
Never again will index == 0 in the recursive calls, so we turn our attention to the else clause.
Here we want to know if we can assign the value i to the next element over, so we check to see if the absolute value of elementToLeft minus i is greater than or equal to 2.
If 'i' is valid to assign in that position (i.e. it is only 1 or 0 different from the value to the left, and 'i' can only get as high as range from the for loop.)
Then we assign it, and check the next position over.
This ends when we have reached the last element in the array.