1286. Iterator for Combination (M)

Iterator for Combination (M)

题目

Design an Iterator class, which has:

  • A constructor that takes a string characters of sorted distinct lowercase English letters and a number combinationLength as arguments.
  • A function next() that returns the next combination of length combinationLength in lexicographical order.
  • A function hasNext() that returns True if 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 true
iterator.next(); // returns "ac"
iterator.hasNext(); // returns true
iterator.next(); // returns "bc"
iterator.hasNext(); // returns false

Constraints:

  • 1 <= combinationLength <= characters.length <= 15
  • There will be at most 10^4 function calls per test.
  • It's guaranteed that all calls of the function next are 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();
    }
}
原文地址:https://www.cnblogs.com/mapoos/p/13503124.html