題目來源:力扣
題目描述:
請你設計一個迭代器類,包括以下內容:
一個構造函數,輸入參數包括:一個 有序且字符唯一 的字符串 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
====================================================
審題:
該題目的核心問題在於從有序且字符唯一的字符串中構建制定長度的子字符串,且子字符串也必須有序.假設需要構建長度爲k的子字符串,我們可以考慮從第一位開始往後選擇可選的字符串.假設子字符串的第i位字符選擇了原字符串中的第r個字符,則爲保持子字符串有序,子字符串後續字符只能從原字符串中的第r+1個字符往後選擇.因此我們可以將該問題出轉化爲回溯問題,在當前步執行每一種可能的選擇,確定第i個元素,然後遞歸地確定第i+1個元素,直到選擇元素個數等於指定的子字符串長度.
java算法:
class CombinationIterator {
String characters;
int combinationLength;
List<String> list;
int curIndex = 0;
private void dfs(String characters, int index, int combinationLength, String curString){
if(curString.length() == combinationLength){ //如果當前選擇長度等於指定長度
list.add(curString);
return;
}
//如果無可選字符,或當前剩餘選擇集大小小於尚需補充的字符個數,則後續選擇無法產生符合要求結果,直接返回
if(index >= characters.length() || characters.length() - index + curString.length() < combinationLength)
return;
//遞歸執行每一個可能選擇,選擇當前位的值
for(int i = index; i < characters.length(); i++){ //可選集合爲[index, characters.length)
dfs(characters, i+1, combinationLength, curString+characters.charAt(i));
}
}
public CombinationIterator(String characters, int combinationLength) {
this.characters = characters;
this.combinationLength = combinationLength;
list = new LinkedList<>();
if (characters != null)
dfs(characters, 0, combinationLength, "");
}
public String next() {
return list.get(curIndex++);
}
public boolean hasNext() {
return curIndex < list.size();
}
}