Java | Time O(n) | Space O(1)
\nclass Solution {\n  /**\n   * Time O(n)\n   * Space O(1)\n   */\n  public String repeatLimitedString(String s, int repeatLimit) {\n    String dic = "abcdefghi
```\nclass Solution {\n  /**\n   * Time O(n)\n   * Space O(1)\n   */\n  public String repeatLimitedString(String s, int repeatLimit) {\n    String dic = "abcdefghijklmnopqrstuvwxyz";\n    // Space O(26)\n    int[] bucket = new int[26];\n    // Time O(n)\n    for (int i = 0; i < s.length(); i++) {\n      bucket[s.charAt(i) - \'a\']++;\n    }\n    \n    // Space O(26)\n    List<Integer> trace = new ArrayList<>();\n    for (int i = 25; i >= 0; i--) {\n      if (bucket[i] > 0) {\n        trace.add(i);\n      }\n    }\n\n    StringBuilder str = new StringBuilder();\n    int cur = 0;\n    int next = 1;\n    int limit = repeatLimit;\n    // Time O(n)\n    while (cur < trace.size() && limit > 0) {\n      str.append(dic.charAt(trace.get(cur)));\n      bucket[trace.get(cur)]--;\n      limit--;\n      if (bucket[trace.get(cur)] == 0) {\n        if (next > trace.size() - 1) {\n          break;\n        }\n        cur = next;\n        next++;\n        limit = repeatLimit;\n      }\n      if (limit == 0) {\n        if (next > trace.size() - 1) {\n          break;\n        }\n        str.append(dic.charAt(trace.get(next)));\n        bucket[trace.get(next)]--;\n        limit = repeatLimit;\n      }\n      if (next < trace.size() && bucket[trace.get(next)] == 0) {\n        next++;\n      }\n    }\n    // Time O(n)\n    return str.toString();\n  }\n}\n```
['Java']