Codingbat challenge: zeroMax Stream API Solution

Viewed 25

Given the task zeroMax zeroMax from CodingBat:

Return a version of the given array where each zero value in the array is replaced by the largest odd value to the right of the zero in the array. If there is no odd value to the right of the zero, leave the zero as a zero.

zeroMax([0, 5, 0, 3]) → [5, 5, 3, 3]
zeroMax([0, 4, 0, 3]) → [3, 4, 3, 3]
zeroMax([0, 1, 0]) → [1, 1, 0]

My solution to this task passes all the tests on CodingBat:

public int[] zeroMax(int[] nums) {
  boolean containsZero = java.util.stream.IntStream.of(nums).anyMatch(x -> x == 0);
  if (!containsZero) {
    return nums;
  }
  
  int[] zeroMax = new int[nums.length];
  int largestOddRight = 0;
  
  for (int i = 0; i < nums.length; i++) {
    if (nums[i] == 0) {
      for (int j = i+1; j < nums.length; j++) {
        if (nums[j] % 2 != 0) {
          if (nums[j] > largestOddRight) {
            largestOddRight = nums[j];
          }
        }
      }
      zeroMax[i] = largestOddRight;
      largestOddRight = 0;
    } else {
      zeroMax[i] = nums[i];
    }
    
  }
  
  return zeroMax;
}

But I have the following question:

How is it possible to solve this task using Stream API ?

Test results

1 Answers

Stream over the indices of your array, check if the current element equals zero, if not map it to itself, if yes stream once again over the rest of your array starting from current position using Arrays.stream(array, from, to) filter odds, find an optional max, if optional present return that orElse return the current element

public int[] zeroMax(int[] nums){
    boolean containsZero = java.util.stream.IntStream.of(nums).anyMatch(x -> x == 0);
    if (!containsZero) {
        return nums;
    }

    return java.util.stream.IntStream.range(0, nums.length).map(
            i -> nums[i] != 0 ? nums[i] : Arrays.stream(nums, i, nums.length)
                                                .filter(j -> j % 2 == 1)
                                                .max()
                                                .orElse(nums[i]))
            .toArray();
}
Related