static SortKey[] rangeBounds(
      int numPartitions, Comparator<StructLike> comparator, SortKey[] samples) {
    // sort the keys first
    Arrays.sort(samples, comparator);
    int numCandidates = numPartitions - 1;
    SortKey[] candidates = new SortKey[numCandidates];
    int step = (int) Math.ceil((double) samples.length / numPartitions);
    int position = step - 1;
    int numChosen = 0;
    while (position < samples.length && numChosen < numCandidates) {
      SortKey candidate = samples[position];
      // skip duplicate values
      if (numChosen > 0 && candidate.equals(candidates[numChosen - 1])) {
        // linear probe for the next distinct value
        position += 1;
      } else {
        candidates[numChosen] = candidate;
        position += step;
        numChosen += 1;
      }
    }

    return candidates;
  }
@Test
  public void testRangeBoundsSkipDuplicates() {
    // step is 3 = ceiling(11/4)
    assertThat(
            SketchUtil.rangeBounds(
                4,
                SORT_ORDER_COMPARTOR,
                new SortKey[] {
                  CHAR_KEYS.get("a"),
                  CHAR_KEYS.get("b"),
                  CHAR_KEYS.get("c"),
                  CHAR_KEYS.get("c"),
                  CHAR_KEYS.get("c"),
                  CHAR_KEYS.get("c"),
                  CHAR_KEYS.get("g"),
                  CHAR_KEYS.get("h"),
                  CHAR_KEYS.get("i"),
                  CHAR_KEYS.get("j"),
                  CHAR_KEYS.get("k"),
                }))
        // skipped duplicate c's
        .containsExactly(CHAR_KEYS.get("c"), CHAR_KEYS.get("g"), CHAR_KEYS.get("j"));
  }