title: Finding the local min/max in a 1D-Array/Histogram
body: <p>I'm trying to find the indices of all the local minima and maxima within an Array.</p>
  
  <p>Example:</p>
  
  <pre><code>int[] array = {5,4,3,3,3,3,3,2,2,2,  6,6,8,5,5,5,3,3,2,1,  1,4,4,7};
  //                             |         |                 |
  // Indices:    0,1,2,3,4,5,6,7,8,9, 10,1,2,3,4,5,6,7,8,9, 20,1,2,3
  // Minima: 8, 20
  // Maxima: 12
  </code></pre>
  
  <p>I came up with an algorithm about which I have few questions:</p>
  
  <ul>
  <li>Is there a much better one? :)</li>
  <li>I used an Enum with methods to achieve this dualism that UP and STRAIGHT_UP are both "UP". Seems messy to me. Any suggestions?</li>
  <li>Do you have better method-names? direction() (+return value) kind of implies that STRAIGHT is not a dir. But at the same time it is, since its an element in the Emum. Hm.</li>
  <li>It works for the given array. Do you see a situation where it does not?</li>
  </ul>
  
  <p>-</p>
  
  <pre><code>import java.util.ArrayList;
  
  
  public class MinMaxFinder {
      private int[] array;
      private ArrayList&lt;Integer&gt; minima;
      private ArrayList&lt;Integer&gt; maxima;
  
  
      private enum Direction{
          UP, DOWN, STRAIGHT_UP, STRAIGHT_DOWN, STRAIGHT;
  
          public Direction direction(){
              if(this==UP || this==STRAIGHT_UP){
                  return UP;
              }else if(this==DOWN || this==STRAIGHT_DOWN){
                  return DOWN;
              }else{
                  return STRAIGHT;
              }
          }
  
          public boolean isStraight(){
              if(this==STRAIGHT_DOWN || this==STRAIGHT_UP || this==STRAIGHT){
                  return true;
              }else{
                  return false;
              }
          }
  
          public boolean hasDifferentDirection(Direction other){
              if(this!=STRAIGHT &amp;&amp; other!=STRAIGHT &amp;&amp; this.direction() != other.direction() ){
                  return true;
              }
              return false;
          }
      }
  
      public MinMaxFinder(int[] array){
          this.array = array;
      }
  
      public void update() {
          minima = new ArrayList&lt;Integer&gt;();
          maxima = new ArrayList&lt;Integer&gt;();
  
          Direction segmentDir = Direction.DOWN;
          int indexOfDirectionChange = 0;
          int prevVal = array[0];
          int arrayLength = array.length; 
          for(int i=1; i&lt;arrayLength; i++){
              int currVal = array[i];
              Direction currentDir = currVal&lt;prevVal?Direction.DOWN:(currVal&gt;prevVal?Direction.UP:Direction.STRAIGHT);
              prevVal = currVal;
  
              if(currentDir.hasDifferentDirection(segmentDir)){
                  int changePos = (indexOfDirectionChange+i-1)/2;
                  if(currentDir.direction() == Direction.DOWN){
                      maxima.add(changePos);
                  }else{
                      minima.add(changePos);
                  }
  
                  segmentDir = currentDir;
                  indexOfDirectionChange = i;
              }else if( currentDir.isStraight() ^ segmentDir.isStraight() ){
                  indexOfDirectionChange = i;
  
                  if(currentDir.isStraight() &amp;&amp; segmentDir.direction()==Direction.UP){
                      segmentDir=Direction.STRAIGHT_UP;
                  }else if(currentDir.isStraight() &amp;&amp; segmentDir.direction()==Direction.DOWN){
                      segmentDir=Direction.STRAIGHT_DOWN;
                  }else{
                      segmentDir = currentDir;
                  }
              }
          }
      }
  
      public ArrayList&lt;Integer&gt; getMinima() {
          return minima;
      }
  
      public ArrayList&lt;Integer&gt; getMaxima() {
          return maxima;
      }
  }
  </code></pre>