Home > OS >  Codingbat challenge: notAlone Stream API Solution
Codingbat challenge: notAlone Stream API Solution

Time:06-12

Given the task notAlone from CodingBat:

We'll say that an element in an array is "alone" if there are values before and after it, and those values are different from it. Return a version of the given array where every instance of the given value which is alone is replaced by whichever value to its left or right is larger.

notAlone([1, 2, 3], 2) → [1, 3, 3]
notAlone([1, 2, 3, 2, 5, 2], 2) → [1, 3, 3, 5, 5, 2]
notAlone([3, 4], 3) → [3, 4]

My solution to this problem passes the vast majority of the tests, but not all of them:

public int[] notAlone(int[] nums, int val) {
  int[] notAlone = new int[nums.length];
  int largestNeighbour = 0;
  
  if (notAlone.length >= 1) {
    notAlone[0] = nums[0];
    notAlone[notAlone.length - 1] = nums[nums.length - 1];
  }
  
  for (int i = 1; i < notAlone.length - 1; i  ) {
    if (nums[i] != val) {
      notAlone[i] = nums[i];
    }
    
    if (nums[i] == val) {
      notAlone[i] = Math.max(nums[i - 1], nums[i   1]);
    }
  }
  
  return notAlone;
}

My questions are the following:

What can be done in order to fix my solution?

Is it possible to solve this task using Stream API ?

Test results

CodePudding user response:

element in an array is "alone" if there are values before and after it, and those values are different from it

Your solution doesn't pass all tests because you're not checking whether the current array element is alone or not, i.e. you're only checking if the current element is equal to the target value, but not if there's an equal element on the left or on the right.

That's how it can be done using streams, the code below passes all tests on CodingBat:

public int[] notAlone(int[] nums, int val) {
    return IntStream.range(0, nums.length)
        .map(i -> isAlone(nums, val, i) ?
            Math.max(nums[i - 1], nums[i   1]) : nums[i])
        .toArray();
}

public boolean isAlone(int[] nums, int val, int i) {
    return nums[i] == val && i > 0 && i < nums.length - 1
        && nums[i - 1] != val && nums[i   1] != val;
}

The imperative code you've provided can be fixed like that (passes all test):

public int[] notAlone(int[] nums, int val) {
    if (nums.length == 0) return nums; // guarding against an empty array
    
    int[] notAlone = new int[nums.length];
    notAlone[0] = nums[0];
    notAlone[nums.length - 1] = nums[nums.length - 1];
    
    for (int i = 1; i < notAlone.length - 1; i  ) {
        if (nums[i] == val && nums[i - 1] != val && nums[i   1] != val) { // is "alone"
            notAlone[i] = Math.max(nums[i - 1], nums[i   1]);
        } else { // is not "alone"
            notAlone[i] = nums[i];
        }
    }
    
    return notAlone;
}
  • Related