题目
请你设计一个迭代器类,包括以下内容:
一个构造函数,输入参数包括:一个 有序且字符唯一 的字符串 characters(该字符串只包含小写英文字母)和一个数字 combinationLength 。
函数 next() ,按 字典序 返回长度为 combinationLength 的下一个字母组合。
函数 hasNext() ,只有存在长度为 combinationLength 的下一个字母组合时,才返回 True;否则,返回 False。
示例:
CombinationIterator iterator = new CombinationIterator(“abc”, 2); // 创建迭代器 iterator
iterator.next(); // 返回 “ab”
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 “ac”
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 “bc”
iterator.hasNext(); // 返回 false
提示:
1 <= combinationLength <= characters.length <= 15
每组测试数据最多包含 10^4 次函数调用。
题目保证每次调用函数 next 时都存在下一个字母组合。
民间解法
- 思路
1.注意两个有序的条件,目标字符串是有序的,返回的选中字符串也是有序的
2.需要记录当前选中的字符串,我这里用数组记录各个选中字符的下标
public class Solution1286 {
}
/**
* 请你设计一个迭代器类,包括以下内容:
*
* 一个构造函数,输入参数包括:一个 有序且字符唯一 的字符串 characters(该字符串只包含小写英文字母)和一个数字 combinationLength 。
* 函数 next() ,按 字典序 返回长度为 combinationLength 的下一个字母组合。
* 函数 hasNext() ,只有存在长度为 combinationLength 的下一个字母组合时,才返回 True;否则,返回 False。
*
*/
class CombinationIterator {
/* 目标字符串 */
String characters;
/* 目标字符串长度 */
int length;
/* 记录组成当前字符串的下标 */
int[] indexArr;
/* 组成字符串的长度 */
int combinationLength;
/* 第一次获取标记 */
boolean isFirst;
public CombinationIterator(String characters, int combinationLength) {
// 初始化类
this.characters = characters;
length = characters.length();
indexArr = new int[combinationLength];
this.combinationLength = combinationLength;
// 刚开始把选中的字符串放在最左边
for (int i=0; i<combinationLength; i++) {
indexArr[i] = i;
}
// 添加是不是第一次获取的标记
isFirst = true;
}
public String next() {
// 获取下一个选中字符串,注意由于输出是强制字符串有序的,所以indexArr下标大的值一定大
if (!isFirst) {
for (int i = combinationLength - 1; i >= 0; i--) {
int index = indexArr[i];
int maxIndex = length - (combinationLength - i);
if (index == maxIndex) {
continue;
} else {
indexArr[i] = index + 1;
for (int j = i + 1; j < combinationLength; j++) {
indexArr[j] = indexArr[j - 1] + 1;
}
break;
}
}
}
isFirst = false;
// 输出
StringBuilder stringBuilder = new StringBuilder();
for (int index : indexArr) {
stringBuilder.append(characters.charAt(index));
}
return stringBuilder.toString();
}
public boolean hasNext() {
if (isFirst) {
return true;
}
// 如果都到了最右边,表示没有下一个选中字符串了
if (indexArr[combinationLength-1] == length-1) {
for (int i=1; i<combinationLength; i++) {
if (indexArr[i] - indexArr[i-1] > 1) {
return true;
}
}
return false;
}
return true;
}
}