Java recursion odd of sum - java

We have to find sum of array and then return if the value is odd (boolean) using recursion
A = {87, 31, 15, 25, 10, 15, 21, 75)
methodname(A, pos) //position is 0 at the begining
i did this so far, but i'm way off since i can't sum and return boolean in the same line
if (pos == array.length-1) {
return A[pos] % 2 != 0
} else {
if (pos < A.length - 1)
return A[pos] + methodname(A, pos + 1) % 2 == 1;
}

public static void main(String[] args) {
System.out.println(isSumOdd(new int[]{3, 3, 4}, 0));
}
private static boolean isSumOdd(int[] arr, int pos) {
return pos == arr.length - 1
? arr[pos] % 2 != 0
: isSumOdd(arr, pos + 1) ^ arr[pos] % 2 != 0; //Sum of 2 numbers can be odd iff exactly one of them is odd.
}

You can try using the following approach (syntax might be wrong, treat the following as pseudo code):
// gives whether the sum from i to end
// is even or odd
Boolean sumIsEven(int[] arr, int i ){
//base case
if(arr.length-1==i){
return arr[i]%2 ==0;
}
if(arr[i]%2 == 0){
return sumIsEven(arr, i +1);
}else{
// arr[i] is odd
return !sumIsEven(arr, i +1);
}
}
But this will give only if the whole sum is odd/even

Related

Multiply an element in a Nested Array by certain value and then add the results together

I am trying to multiply each "column" of an array by a specific number, and then sum up the results for each "row".
I was able to figure out how to do this for a single array, but I am having trouble figuring this out for a 2d-array.
I need to do this recursively, so no loops. Can anybody provide a pseudocode, or explain what steps I should be taking for each column?
public static int didIt(int[] d, int n) {
//base or terminating condition
if (n <= 0) {
return 0;
}
if (n == 1) {
return didIt(d, n - 1) + d[n - 1] * 10;
}
if (n == 2) {
return didIt(d, n - 1) + d[n - 1] * 50;
}
if (n == 3) {
return didIt(d, n - 1) + d[n - 1] * 22;
}
if (n == 4) {
return didIt(d, n - 1) + d[n - 1] * 7;
}
if (n == 5) {
return didIt(d, n - 1) + d[n - 1] * 45;
} else {
return didIt(d, n - 1) + d[n - 1];
}
}
public static void main(String[] args) {
int[] array2 = {1, 2, 3, 4, 5};
System.out.println(didIt(array2, array2.length));
}
How would I turn this code into a 2d-array version?
Update
Since you need every "row" to be treated in the same way you can recursively add up the total calculated for every nested array by moving position in the matrix with every recursive call:
public static int arrSum(int[] arr, int pos) {
if (pos == arr.length) { // base case
return 0;
}
return arr[pos] + arrSum(arr, pos + 1); // recursive case
}
Your condition logic can be brushed up like that:
public static int arrSum(int[] arr, int pos) {
if (pos == arr.length) { // base case
return 0;
}
if (pos == 0) {
return 10 * arr[pos] + arrSum(arr, pos + 1);
}
if (pos == 1) {
return 50 * arr[pos] + arrSum(arr, pos + 1);
}
if (pos == 2) {
return 22 * arr[pos] + arrSum(arr, pos + 1);
}
if (pos == 3) {
return 7 * arr[pos] + arrSum(arr, pos + 1);
}
if (pos == 4) {
return 45 * arr[pos] + arrSum(arr, pos + 1);
}
return arr[pos] + arrSum(arr, pos + 1);
}
This part is related to the Initial version of the Question
You don't need redundant conditional logic repeated for every hard-coded value of n.
As well as there's no need to multiply each element of the array by 10, instead we can multiply by 10 the overall sum.
That's how your recursive method that calculates the array sum can be fixed:
public static int arrSum(int[] arr, int pos) {
if (pos == arr.length) { // base case
return 0;
}
return arr[pos] + arrSum(arr, pos + 1); // recursive case
}
And that how you can calculate the sum of the elements of a nested array (the logic is almost the same):
public static int matrixSum(int[][] matrix, int pos) {
if (pos == matrix.length) { // base case
return 0;
}
return arrSum(matrix[pos], 0) + matrixSum(matrix, pos + 1); // recursive case
}
main()
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
System.out.println(matrixSum(matrix, 0) * 10);
}
Output:
450 // sum of numbers from 1 to 9 equels 45, and * 10 = 450
Sidenote: in Java there's no 2d-arrays (so this term isn't correct accurate). We can create a nested array - an array that is composed of other arrays.
You can still use same logic; just change how you can call your didIt method:
public static void main(String[] args) {
int[][] arr = { { 1, 1, 1, 1 },
{ 2, 2, 2, 2 },
{ 3, 3, 3, 3 } };
for(int a[]: arr) {
System.out.print(didIt(a,a.length));
}
No need to change anything in didIt.
Also, I assume your didIt which you showed here is for demonstraion purpose, otherwise there is plenty of repeated code in if which you can able to avoid.

longest Flat Sequence - recursion problem

First of all I'm a beginner programmer and I'm pretty sure I have quite a few errors in the code.
I'm stuck in code in the exercise,
sequence flat of integers if all the numbers in it are the same number or the series consists of two consecutive number,
I need to write a recursive method which receives an array of integers, and returns the length of the maximum subset which is a flat series.
For example for this array:
(4, 5, 6, 5, 4, 3)
The method will return 3. Since the sub-arrays that make up the flat series in the array are:
(4, 5) - Length 2.
(5, 6, 5) - Length 3.
(5, 4) - Length 2.
(4, 3) - Length 2.
The longest flat sub-series in the array is 3 in length, which is the value to be returned.
public static int longestFlatSequence (int[] arr)
{
return lengthFlat (arr, 0, 0);
}
private static int lengthFlat (int[] arr, int i, int max)
{
if (arr.length >= 1)
{
return arr.length;
}
if (i + 1 <= arr.length -1)
{
if (arr[i] == arr[i+1] || arr[i] + 1 == arr[i+1])
{
int val = lengthFlatSequence(arr,i,i+1);
if (val > max)
{
max = val;
}
}
return lengthFlat(arr, i+1, max);
}
return max;
}
private static int lengthFlatSequence(int[] arr, int i, int curr)
{
if (i == arr.length - 1)
{
return curr;
}
int min = 0;
if (arr[i] < arr[i+1])
{
min = arr[i];
}else{
min = arr[i+1];
}
if (min == arr[curr] || min + 1 == arr[curr])
{
return lengthFlatSequence(arr, i, curr);
}else{
return curr;
}
}
Please help me fix the code.
Thank you!

How to manage recursive function?

I need to write a recursive function that gets 4 parameters.
The 1st one is array. the 2nd one - left index, the 3rd one a right index and "K" index. "K" index is a cell in array , and the lrft index points to the start and the right one points to the end.
An array may contain such digitalis as zeros and ones. The method returns the maximum length of a sequence of ones that contain the cell k.
Here the example of the result that I need to get:
public static void main(String[] args) {
int[] A = {1,1,1,0,1,1,0,1,1,1,1,1,0,1,1};
System.out.println(floodOnes(A,0, A.length-1, 9)); // 5 output
System.out.println(floodOnes(A,0, A.length-1, 3)); // 0 output
System.out.println(floodOnes(A,0, A.length-1, 0)); // 3 output
System.out.println(floodOnes(A,0, A.length-1, 14)); // 2 output
}
public static int floodOnes(int [] A,int left, int right, int k){
//some logic
}
Here is my implementation:
public class Program {
public static void main(String[] args) {
int[] A = {1,1,1,0,1,1,0,1,1,1,1,1,0,1,1};
System.out.println(floodOnes(A,0,A.length-1, 9));
}
public static int floodOnes(int [] A,int left, int right, int k){
if (left != k) left+=1;
if (right != k) right-=1;
if (left == k && right == k) return A[k]; //condition when the recursive call stops
int res = floodOnes(A, left, right, k);
if (A[left] == 1 && A[right] == 1)
return res = A[left] + A[right]; //count ones
else return res;
}
}
But my solution not working properly.
In this rows:
if (A[left] == 1 && A[right] == 1)
return res = A[left] + A[right]; //count ones
If one of the conditions isn`t executed once, the following returns shouldn't add ones to result variable.
And I don't know how to do it.
I proved my comment wrong. Here is a recursive method with the 4 parameters mentioned in the question that indeed solves the problem.
public static int floodOnes(int[] a, int left, int right, int k) {
if (0 <= left && left <= k && k <= right && right < a.length) {
// is there a 0 between left (inclusive) and k (exclusive)?
int i = left;
while (i < k && a[i] == 1) {
i++;
}
if (i < k) {
assert a[i] == 0;
return floodOnes(a, i + 1, right, k);
}
// is there a 0 between k (exclusive) and right (inclusive)?
i = right;
while (i > k && a[i] == 1) {
i--;
}
if (i > k) {
assert a[i] == 0;
return floodOnes(a, left, i - 1, k);
}
// no zero found, a[k] not checked, though
if (a[k] == 0) {
return 0;
} else {
return right - left + 1;
}
} else {
throw new IllegalArgumentException("Expected " + left + " <= " + k + " <= " + right + " < " + a.length);
}
}
With this method, the first main method in your question prints the expected:
5
0
3
2
I really don’t see a point in solving the problem in this way, so I am far from sure this was what was intended. I’d prefer a non-recursive solution, or if it just needs to be recursive somehow, then the solution in Grzegorz Górkiewicz’ answer.
You can decompose this problem into 2 functions.
The first will count elements on the left-hand side, the latter on the right-hand side. Both use recursion.
public static int floodOnes(int[] A, int left, int right, int k) {
return checkLeft(A, left, k-1, A[k]) + 1 + checkRight(A, right, k+1, A[k]);
}
public static int checkLeft(int[] A, int leftBoundary, int k, int number) {
if (k < 0 || A[k] != number || k < leftBoundary)
return 0;
return 1 + checkLeft(A, leftBoundary, k-1, number);
}
public static int checkRight(int[] A, int rightBoundary, int k, int number) {
if(k >= A.length || A[k] != number || k > rightBoundary)
return 0;
return 1 + checkRight(A, rightBoundary, k+1, number);
}
I assume:
that 0 <= left <= k <= right < A.length;
that the solitary number should be counted as 1 (sequence of length 1) unlike your example. If you want it to be counted as 0, add if(A[k] != 1) return 0; or a similar condition in your floodOnes method.
Therefore:
System.out.println(floodOnes(A, 0, A.length - 1, 9)); // prints 5
System.out.println(floodOnes(A, 0, A.length - 1, 3)); // prints 1
System.out.println(floodOnes(A, 0, A.length - 1, 0)); // prints 3
System.out.println(floodOnes(A, 0, A.length - 1, 14)); // prints 2
Besides left and right parameters can be used for some input exceptions
(e.g. k > A.length).
Since you are looking for - the maximum length of a sequence of ones that contain the cell k. A simple and concise code to achieve this can be as follows.
public static void main(String[] args) {
int[] A = {1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1};
System.out.println(floodOnes(A, 0, A.length - 1, 9)); // prints 5
System.out.println(floodOnes(A, 0, A.length - 1, 3)); // prints 0
System.out.println(floodOnes(A, 0, A.length - 1, 0)); // prints 3
System.out.println(floodOnes(A, 0, A.length - 1, 14)); // prints 2
}
public static int checkLeft(int[] A, int k) {
return (k < 0 || A[k] != 1) ? 0 : 1 + checkLeft(A, k - 1);
}
public static int checkRight(int[] A, int k) {
return (k > (A.length - 1) || A[k] != 1) ? 0 : 1 + checkRight(A, k + 1);
}
public static int floodOnes(int[] A, int left, int right, int k) {
return (A[k] != 1) ? 0 : checkLeft(A, k - 1) + 1 + checkRight(A, k + 1);
}
It outputs the desired result.
5
0
3
2

How to iterate over array of integers to find a sequence based on an O(N) solution?

I saw following question and tried to find an answer for that.
Question: Given a sequence of positive integers A and an integer T, return whether there is a *continuous sequence* of A that sums up to exactly T
Example
[23, 5, 4, 7, 2, 11], 20. Return True because 7 + 2 + 11 = 20
[1, 3, 5, 23, 2], 8. Return True because 3 + 5 = 8
[1, 3, 5, 23, 2], 7 Return False because no sequence in this array adds up to 7
Note: We are looking for an O(N) solution. There is an obvious O(N^2) solution which is a good starting point but is not the final solution we are looking for.
My answer to above question is:
public class Tester {
public static void main(String[] args) {
int[] myArray = {23, 5, 4, 7, 2, 11};
System.out.println(isValid(myArray, 20));
}
public static boolean isValid(int[] array, int sum) {
int pointer = 0;
int temp = 0;
while (pointer < array.length)
{
for (int i = pointer; i < array.length; i++)
{
if (array[i] > sum)
break;
temp += array[i];
if (temp == sum)
return true;
else if (temp > sum)
break;
// otherwise continue
}
temp = 0;
pointer++;
}
return false;
}
}
I think my answer is O(N^2) which is not acceptable based on Question. Is there a solution based on O(N)?
You only need to loop once actually which is O(N).
Start adding from index 0 and once you exceed the sum start removing from the beginning of the array. if temp falls below sum continue looping.
public static boolean isValid(int[] array, int sum) {
int init = 0,temp = 0;
for (int i = 0; i < array.length; i++) {
temp += array[i];
while (temp > sum) {
temp -= array[init];
init++;
}
if (temp == sum)
return true;
}
return false;
}
What you should do is to have two indices (start and stop) then you increase stop until the sum is the required (and return true) or above. Then you increase start until the sum is the required (and return true or below. Then you repeat this until you reach the end of the array. You can update the sum incrementally (add the element when you increase stop and subtract when you increase start). This ought to be O(N).
Here's an example:
public class t {
public static void main(String[] args) {
int[] myArray = {23, 5, 4, 7, 2, 11};
System.out.println(isValid(myArray, 20));
}
public static boolean isValid(int[] array, int sum) {
int start = 0;
int stop = 0;
int tsum = 0;
while( true )
{
if( tsum < sum )
{
if( stop >= array.length )
break;
tsum += array[stop];
stop++;
}
else if( tsum > sum )
{
tsum -= array[start];
start++;
}
else if( tsum == sum )
return true;
// System.out.println(start + " -- " + stop + " => " + tsum);
}
return false;
}
}

Arrays in Java - Core Java

In This Question A value is "everywhere" in an array if for every pair of adjacent elements in the array, at least one of the pair is that value. Return true if the given value is everywhere in the array.
isEverywhere({1, 2, 1, 3}, 1) → true,coz 1 is present in(1,2) and (1,3)
isEverywhere({1, 2, 1, 3}, 2) → false,coz 2 is in (1,2) but not in (1,3)
isEverywhere({1, 2, 1, 3, 4}, 1) → false,coz 1 is present in 2 pairs (1,2) and (1,3) but 4 is not having a pair of 1
My Partial working code is below,could you help me out with this problem,stuck up for a long time.
::Code::
public boolean isEverywhere(int[] nums, int val) {
boolean flag = false;
for(int i=0;i<nums.length;i++){
for(int j=i+2;j<nums.length;j++){
if(nums[i] == nums[j]){
flag = true;
}
}
}
return flag;
}
Result expected:
`Expected` `This` `Run`
isEverywhere({1, 2, 1, 3}, 1) → true true OK
isEverywhere({1, 2, 1, 3}, 2) → false true X
isEverywhere({1, 2, 1, 3, 4}, 1) → false true X
Try this:
boolean isEverywhere(int[] nums, int val) {
// use i+=2 to get start index of pair.
for(int i=0;i<nums.length;i+=2) {
// other index in the pair.
int j = i + 1;
// make sure the other index really exists.
if(j < nums.length) {
// if it exists..and val is not equal to
// either in the pair..return false.
if(nums[i] != val && nums[j] != val) {
return false;
}
} else {
// no pair..one element case.
// return true if that element is val..else return false.
return nums[i] == val;
}
}
// array has no unpaired element..and all pairs have val.
return true;
}
The key is
for every pair of adjacent elements in the array
Print out i and j before if(nums[i] == nums[j]) and you'd see what's going on.
For an array of length 2, you need (0, 1), for array of length 3, you need (0, 1), (1, 2), and so on.
You never use val in your code
Try figuring out the logic for that first
And this can be done with a single loop, try to figure out how you would as a person apply an algorithm, then code it
Your code is failing because the flag does not turn off in the case that the second loop goes beyond the array length.
Not a full solution, but if the length of the array is odd, check that the last value equals the target val
...
if( !(nums.length % 2) == 0 ){
if( nums[length-1] != val){
return false;
}
}
...
I did mine by simply counting if there are spaces:
Here it is in it's simple glory:
public boolean isEverywhere(int[] nums, int val) {
//Create an int to count the number of spaces between each instance of val.
int counter = 0;
//Create a for loop that checks val;
for (int i = 0; i < nums.length; i++)
{
//If the number at iteration i != val;
if (nums[i] != val)
{
//We increment the counter by one.
counter++;
}
//If the number does equal val, we put the counter back to 0;
else
{
counter = 0;
}
//If the counter is greater than or equal to two,
//We know that there is a space of more than 2, and so
//We return false;
if (counter >= 2)
{
return false;
}
}
//Return true if not false;
return true;
}
This code works fine:-
public boolean isEverywhere(int[] nums, int val) {
for(int i=0;i<=nums.length-2;i++){
if(nums[i]!=val&&nums[i+1]!=val){
return false;
}
}
return true;
}
public class IE {
static boolean isEverywhere(int[] a, int val) {
for (int i = 0; i < a.length; i++) {
System.out.println("*** iteration: " + i);
System.out.println("a[" + (i-1) + "]=" + (i > 0 ? a[i-1] : "n/a"));
System.out.println("a[" + i + "]=" + a[i]);
System.out.println("a[" + (i+1) + "]=" + (i < a.length -1 ? a[i+1] : "n/a"));
if (a[i] != val && (i > 0 ? a[i-1] != val : true) && (i < a.length-1 ? a[i+1] != val : true)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int[] a = new int[] {1, 2, 1, 3};
System.out.println(isEverywhere(a, 1));
a = new int[] {1, 2, 1, 3};
System.out.println(isEverywhere(a, 2));
a = new int[] {1, 2, 1, 3, 4};
System.out.println(isEverywhere(a, 1));
}
}
Basically, for a given element in the array, the test fails if the value isn't adjacent, either before or after it.

Categories

Resources