-3

I am doing a code challenge where given two integers l and r, I have to print all the odd numbers between i and r (i and r inclusive). The function must return an array of integers denoting the odd numbers between l and r.

This is what I have so far

 static List<Integer> oddNumbers(int l, int r) {
    List<Integer> list1 = new ArrayList<>();
    if ((r > l) && (l >= 1) && (r <= 100000)) {
        for (int i = tmp; tmp < r; i++) {
            if (l % 2 == 0)
               l = l + 1;              
            list1.add(l);
            l = l + 2;
        }
    }
    return list1;
}

However, I received several errors like this

Compiler Message
Wrong Answer
Your Output (stdout)
Output hidden

Any ideas for this? on the QA of the challenge site, it seems related to Corner case problems.

Mike Yang
  • 2,581
  • 3
  • 24
  • 27

4 Answers4

4

I would suggest the following code :

public static List<Integer> getOdd(int l, int r) {
    List<Integer> odd = new ArrayList<Integer>();
    if (l % 2 == 0)
        l++;
    while(l <= r) {
        odd.add(l);
        l += 2;
    }
    return odd;
}
Karim
  • 187
  • 10
  • 1
    seriously? why? first of all, it has to return an array, not a list, secondly, why would you want to compare all values to check if they are odd/even, if you can just get the first odd one, and add 2 each iteration, instead of re-checking every time? – Stultuske Mar 12 '19 at 09:51
  • I saw in @Yang 's example that he was returning a list. And yeah you're right, it's better to get the first odd number and add 2. – Karim Mar 12 '19 at 10:13
  • Indeed, he returns a list. He also receives a compiler error message, which might very well be caused by returning a list. – Stultuske Mar 12 '19 at 10:15
  • I did edit my answer to avoid re-checking every time, but for the List I really don't know because he didn't specify anything. Anyway thanks for your answers ! – Karim Mar 12 '19 at 10:20
  • as his requirement description states: "The function must return an array of integers" – Stultuske Mar 12 '19 at 10:21
1

As the comments have mentioned, you're excluding r in your loop and are perhaps returning the wrong data structure?

Moreover, your code is doing way more than it needs to

  • you only need one loop
  • you don't need tmp at all - just modify l
  • you don't need all the if/else blocks

I suggest the following:

static int[] oddNumbers(int l, int r) {
    List<Integer> list1 = new ArrayList<>();
    if (l % 2 == 0) l++;
    for(; l <= r; l += 2) {
        list1.add(l);
    }
    return list1.stream().mapToInt(i->i).toArray(); // https://stackoverflow.com/a/23945015/2554605
}

You can add back the if ((r >= l) && (l >= 1) && (r <= 100000)) if it's needed based on challenge requirements, but I'm not that it's necessary (notice I have r >= l instead of just r > l to cover the case where r == l).

As well, if you really are allowed to return List<Integer> instead of int[], then just return list1; instead as you had it.

Michael Yaworski
  • 13,410
  • 19
  • 69
  • 97
  • just a thought. so far as I can tell, the limits (inclusive) are l and r, but unless the requirement on that page is different compared to the one posted here, it's not stated which of the two is the upper, and which the lower limit. – Stultuske Mar 12 '19 at 10:16
  • @Stultuske I figure the `l` and `r` are self-explanatory due to their names. I suppose if it were generic `a` and `b` though, we could swap the values if `a > b` and keep our logic the same. – Michael Yaworski Mar 12 '19 at 12:09
  • how are i and r self-explanatory? might be because I myself am not a native English speaker, but still .. – Stultuske Mar 12 '19 at 12:13
  • @Stultuske I believe it's `l`, not `i`. I know OP said `i` but it really doesn't make sense because he starts with `l`. And `l` is short for `left`; `r` is short for `right`. So `r` is upper bound is `l` is lower bound. – Michael Yaworski Mar 12 '19 at 12:15
0

this version should be working

 static List<int> oddNumbers(int l, int r)
    {
        List<int> list1 = new List<int>();
        if ((r > l) && (l >= 1) && (r <= 100000))
        {
            int tmp = l % 2 == 0 ? l + 1 : l;            
            for (int i = tmp; i < r; i += 2)
            {
                list1.Add(i);
            }

        }
        return list1;
    }
Oleg Bondarenko
  • 1,694
  • 1
  • 16
  • 19
0

Instead of dividing by 2 and checking if the remainder is 0 or 1, you can bitwise and with 1(&1) and it will look like this if ((number&1)==1) then the number is odd, it reduce complexity.

bguiz
  • 27,371
  • 47
  • 154
  • 243