0

I just had an online interview and was asked a neat question. Thought I would share it with the community, along with my answer. See if you think my answer is correct and if not - how would you improve on it? I think this could benefit any people like me with relatively short coding experience, trying to make their first steps.

Note - the problem did not have an explanation in the body - had to figure out the functionality on my own. What the function does is return the the first instance of char a or char b in a given String s or -1 if either not found.

Problem

Simplify the implementation below as much as you can. Even better if you can also improve performance as part of the simplification! FYI: This code is over 35 lines and over 300 tokens, but it can be written in 5 lines and in less than 60 tokens.

static int func(String s, char a, char b)
{
    if (s.isEmpty()) return -1;

    char[] strArray = s.toCharArray();

    int i=0;
    int aIndex=-1;
    int bIndex=-1;
    while (aIndex==-1 && bIndex==-1 && i<strArray.length)
    {
        if (strArray[i] == a)
            aIndex=i;
        if (strArray[i] == b)
            bIndex=i;
        i++;
    }


    if (aIndex != -1)
    {
        if (bIndex == -1)
            return aIndex;
        else
            return Math.min(aIndex, bIndex);
    }
    else
    {
        if (bIndex != -1)
            return bIndex;
        else
            return -1;
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Amos Bordowitz
  • 474
  • 6
  • 19
  • 2
    I'd recommend commenting the code and specifying exactly what it should do, then underline the actual problems and how you solved it. Finally I'd move everything [here](http://codereview.stackexchange.com/). – Mena Sep 21 '15 at 10:08
  • @HimBromBeere That's actually encouraged behaviour. As long as your Q&A is helpful, why not answer it yourself? See [here](http://stackoverflow.com/help/self-answer). You'll note it doesn't say you need to later discover the answer to the problem, there's even a way to immediately post a question and answer at the same time. – SuperBiasedMan Sep 21 '15 at 10:12
  • @Mena Given that you can replace all the code with a single line (see answer), I'm not sure how appropriate it would be on Code Review. Is it appropriate for [so]? Probably not in its current state, although it may be editable to be so. – Bernhard Barker Sep 21 '15 at 10:18
  • @Dukeling well, Code Review allows questions asking to improve current code. Which is OP's essential question: "have I improved it well enough?". The problems I see with the current question is that it's all introduction and code, but no functional description on scope. Definitely not a great SO question but could be salvaged in Code Review, in my opinion. – Mena Sep 21 '15 at 10:20
  • @Mena Impotrtant: I copied and pasted the question AS IS. But I'll add a functional description to make the post better – Amos Bordowitz Sep 21 '15 at 10:22

5 Answers5

5

Analysis

The given code works this way:

  • check if the String is empty => return -1
  • while loop stops if:
    • the index of char a is found
    • the index of char b is found
    • both indices are found
    • the index is larger than the given String
  • there are three possible return values
    • if a (or a and b) is found => return aIndex
    • if b is found => return bIndex
    • if nothing is found => return -1

Solution

No one was thinking of the simplest and in my opinion fastest solution. Every one else is calling indexOf twice and therefore iterating twice over the String.

public int func(String s, char a, char b) {
  for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    if (c == a || c == b) {
      return i;
    }
  }
  return -1;
}

Benchmark results

Setup

The char 'x' and 'z' are quite in the middle of the String. The test string contains 10000 chars.

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;

@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@Measurement(iterations = 10, timeUnit = TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Threads(1)
@Warmup(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

  String s = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. \r\n"
      + "\r\n"
      + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \r\n"
      + "\r\n"
      + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. \r\n"
      + "\r\n"
      + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. \r\n"
      + "\r\n"
      + "Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. \r\n"
      + "\r\n"
      + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \r\n"
      + "\r\n"
      + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. \r\n"
      + "\r\n"
      + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. \r\n"
      + "\r\n"
      + "Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. \r\n"
      + "\r\n"
      + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \r\n"
      + "\r\n"
      + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. \r\n"
      + "\r\n" + "Duis au";

  char a = 'x';
  char b = 'z';

  @Benchmark
  public int testLong() {
    if (s.isEmpty()) {
      return -1;
    }

    char[] strArray = s.toCharArray();

    int i = 0;
    int aIndex = -1;
    int bIndex = -1;
    while (aIndex == -1 && bIndex == -1 && i < strArray.length) {
      if (strArray[i] == a) {
        aIndex = i;
      }
      if (strArray[i] == b) {
        bIndex = i;
      }
      i++;
    }

    if (aIndex != -1) {
      if (bIndex == -1) {
        return aIndex;
      } else {
        return Math.min(aIndex, bIndex);
      }
    } else {
      if (bIndex != -1) {
        return bIndex;
      } else {
        return -1;
      }
    }
  }

  @Benchmark
  public int testIndexOf1() {
    return Math.max(s.indexOf(a), s.indexOf(b));
  }

  @Benchmark
  public int testSubstring() {
    return func(s, a, b);
  }

  private int func(String s, char a, char b) {
    if (s.length() <= 0) {
      return -1;
    } else if (s.charAt(0) == a || s.charAt(0) == b) {
      return 0;
    } else {
      int r = func(s.substring(1), a, b);
      return r < 0 ? -1 : r + 1;
    }
  }

  @Benchmark
  public int testLoop() {
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (c == a || c == b) {
        return i;
      }
    }
    return -1;
  }
}

Results

Benchmark                  Mode  Cnt        Score        Error  Units
MyBenchmark.testIndexOf1   avgt   30      949,729 ±     14,753  ns/op
MyBenchmark.testLong       avgt   30     4044,216 ±    122,244  ns/op
MyBenchmark.testLoop       avgt   30      725,502 ±     38,688  ns/op
MyBenchmark.testSubstring  avgt   30  3549335,410 ± 133681,449  ns/op
Flown
  • 11,480
  • 3
  • 45
  • 62
1

If @Amos Bordowitz's answer is working, I think mine too.

static int func(String s, char a, char b)
{
    return Math.max(s.indexOf(a), s.indexOf(b));
}

Why should I care about s.indexOf(a) == s.indexOf(b)? The Max() is always working even if they are same.

J.C
  • 633
  • 1
  • 13
  • 27
  • I edited my answer. Switched to Math.min. See if still relevant. If so - I probably didn't get the job haha – Amos Bordowitz Sep 21 '15 at 10:10
  • @AmosBordowitz Well, I don't really read and understand your original question, but not only `Max()` but also `Min()` are still working even if `s.indexOf(a) == s.indexOf(b)`, so just edit my answer from `Max` to `Min`, and it should works (if yours is working). – J.C Sep 21 '15 at 10:12
  • @AmosBordowitz The point is that if `a == b` then it doesn't matter which you return, they'll both give the same result. And returning `min(a, b)` is the same as returning either `a` or `b`. Though I don't know how this impacts performance. – SuperBiasedMan Sep 21 '15 at 10:15
  • actually your original actually works. I didn't think about it all the way. Edit it back to max and I'll accept your answer :) – Amos Bordowitz Sep 21 '15 at 10:15
  • 1
    I do not think this works. Let s="Hello a b", a="a", b="b". The answer is 6. But your function would return 8. – emory Sep 21 '15 at 10:25
  • Sorry J.C, had to award the correct answer to @Flown. His was correct. emory's remark was spot on. – Amos Bordowitz Sep 21 '15 at 10:40
  • @emory I don't really think my answer is working, please notice I said "If Amos' answer is working". My point is check `s.indexOf(a) == s.indexOf(b)` in his answer is not necessary. – J.C Sep 22 '15 at 01:50
  • @AmosBordowitz It's okay since I wasn't going to provide correct answer. My point is what I just reply to emory. – J.C Sep 22 '15 at 01:52
0

My answer:

static int func(String s, char a, char b)
{
    if (s.indexOf(a) != s.indexOf(b)) 
        return Math.min(s.indexOf(a), s.indexOf(b));
    else if (s.indexOf(a) == s.indexOf(b))
        return s.indexOf(a);
}

//returning Min(a,b) is redundant. it will always be -1
Amos Bordowitz
  • 474
  • 6
  • 19
0

The below code is less concise than the solutions posted, but I believe it is faster. The other solutions that I see iterate over the string twice: O(2n). The below code iterates over the string once O(n).

Though in practice, this should not matter and I would go with the other (more clear) solution.

static int func(String s, char a, char b){
      if(s.length<=0){
            return -1;
      }else{
            char c = s.charAt(0);
            if((c==a)||(c==b)){
                 return 0;
            }else{
                int r = func(s.substring(1), a, b);
                return r<0?-1:r+1;
            }
     }
 }
emory
  • 10,725
  • 2
  • 30
  • 58
0

If you want to shorten your code, I think this is what you want

static int func(String s, char a, char b)
{
    if (s.isEmpty()) return -1;
    int n1=s.indexOf(a);
    int n2=s.indexOf(b);

    return (n1>n2?(n2>-1?n2:n1):(n1>-1?n1:n2));
 }
Deepankar Singh
  • 662
  • 1
  • 9
  • 20
  • while this is elegant, it was really hard for me to come up with a good ternary return statement under the pressure of the interview. – Amos Bordowitz Sep 21 '15 at 10:42
  • 1
    this nothing but multiple if else statements combined into one. just think over it, its not so difficult. :) – Deepankar Singh Sep 21 '15 at 10:44
  • This is absolutely unreadable. Nobody wants to maintain such code – Thomas Weller Sep 21 '15 at 10:50
  • 1
    It might be difficult to understand in one go but not Absolutely unreadable. :D . Well i was just suggesting a way how he can compress his code what OP wants. – Deepankar Singh Sep 21 '15 at 10:56
  • 1
    @Thomas It seems that the purpose of the method is well defined and it is correctly implemented. Why would anyone need to maintain it. In production, we would give it a better name, write some javadocs, unit test it, and then use it. – emory Sep 21 '15 at 11:23