题目
Design an Iterator class, which has:
- A constructor that takes a string
charactersof sorted distinct lowercase English letters and a numbercombinationLengthas arguments. - A function next() that returns the next combination of length
combinationLengthin lexicographical order. - A function hasNext() that returns
Trueif and only if there exists a next combination.
Example:
CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator.iterator.next(); // returns "ab"iterator.hasNext(); // returns trueiterator.next(); // returns "ac"iterator.hasNext(); // returns trueiterator.next(); // returns "bc"iterator.hasNext(); // returns false
Constraints:
1 <= combinationLength <= characters.length <= 15- There will be at most
10^4function calls per test. - It’s guaranteed that all calls of the function
nextare valid.
题意
给定一个字符串s和一个整数k,从s中选出k个字符组成排列,按顺序求出每一个排列。
思路
维护一个长度为k的数组selected,selected[i]表示当前排列中第i个字符在s中的下标。显然,为了使一个排列合法,selected[i]不能超过一个特定的值(s.length-(selected.length-i)),不然s中剩余的字符个数不足以填充到k。如果selected[i]小于这个特定值,则只要将selected[i]指向下一个字符,并重置i之后所有的位置为其第一个合法位置,即可得到下一个排列;如果selected[i]等于这个特定值,则缩小i重复操作。
代码实现
Java
class CombinationIterator {private String s;private int[] selected;private boolean init;public CombinationIterator(String characters, int combinationLength) {s = characters;selected = new int[combinationLength];for (int i = 0; i < combinationLength; i++) {selected[i] = i;}init = true;}public String next() {if (init) {init = false;return generate();}for (int i = selected.length - 1; i >= 0; i--) {int end = s.length() - (selected.length - i);if (selected[i] < end) {selected[i]++;int j = 1;while (i + j < selected.length) {selected[i + j] = selected[i] + j;j++;}break;}}return generate();}public boolean hasNext() {return s.length() - selected[0] > selected.length;}private String generate() {StringBuilder sb = new StringBuilder();for (int i = 0; i < selected.length; i++) {sb.append(s.charAt(selected[i]));}return sb.toString();}}
