The idea is simple: first we collect all the available numbers and sort them, then scan the input string from the last index. If at index i, there is a number that is greater than the current number at i, we replace it with the greater number and for all the number after i, we set them to the smallest number we have.

If there is no solution, just return the time constructed by smallest number.

```
public String nextClosestTime(String time) {
int[] num = new int[4];
char[] t = time.toCharArray();
for (int i = 0, j = 0; i < t.length; i++) if (t[i] != ':') num[j++] = t[i] - '0';
Arrays.sort(num);
for (int i = 4; i >= 0; i--) {
if (t[i] == ':') continue;
for (int j = 0; j < 4; j++) {
if (num[j] > t[i] - '0') {
t[i] = (char)('0' + num[j]);
for (int k = i + 1; k < 5; k++) if (t[k] != ':') t[k] = (char)(num[0] + '0');
if ((t[0] - '0') * 10 + (t[1] - '0') <= 23 && (t[3] - '0') * 10 + (t[4] - '0') <= 59) return new String(t);
}
}
}
for (int i = 0; i < 5; i++) if (t[i] != ':') t[i] = (char)(num[0] + '0');
return new String(t);
}
```