每日一题之字母组合迭代器

2020-04-13  本文已影响0人  this_is_for_u

题目1286:字母组合迭代器

请你设计一个迭代器类,包括以下内容:

示例

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:由于最近都是在做回溯类型的算法题,这题在回溯类型下,所以先使用回溯方法做了一遍,就是先顺序列出所有的字母组合值存到容器里,之后顺序的取出来。

方法2:使用二进制编码方式,拿"abcd",2举例,字典序排序应该如下:

ab
ac
ad
bc
bd
cd

对应的二进制如下

1100
1010
1001
0110
0101
0011

可以看出二进制是从大到小排列的,所以可以找出二进制1的个数等于字符串个数的数字,按照二进制编码从大到小的顺序,将字典序排序的字符串依次列举出来。

代码

方法1:

class CombinationIterator {
   public:
    CombinationIterator(string characters, int combinationLength) {
        dfs(characters, combinationLength, 0, "");
    }

    void dfs(string str, int len, int index, string path) {
        if (path.size() == len) {
            paths.push_back(path);
            return;
        }

        for (int i = index; i < str.size(); i++) {
            dfs(str, len, i + 1, path + str[i]);
        }
    }

    string next() {
        string str = paths[0];
        paths.pop_front();
        return str;
    }

    bool hasNext() { return paths.size() > 0; }

   private:
    deque<string> paths;
};

方法2:

class CombinationIterator {
public:
    CombinationIterator(string characters, int combinationLength) {
        reverse(characters.begin(), characters.end());
        this->characters = characters;
        this->cur = (1 << characters.size()) - 1;
        this->combinationLength = combinationLength;
    }
    
    int Count(int n){
        int count = 0;
        while (n != 0){
            count++;
            n = (n-1) & n;
        }
        return count;
    }
    
    string next() {    
        while (cur >= 0 && Count(cur) != combinationLength) {
            cur--;
        }
        
        string res;
        for (int i = 0; i < characters.size(); ++i) {
            if (cur & (1 << i)) { 
                res = characters[i] + res;
            }
        }
        cur--;
        
        return res;
    }

    bool hasNext() {  
        while (cur >= 0 && Count(cur) != combinationLength) {
            cur--;
        }
        if (cur < 0) {
            return false;
        }
        return true;
    }
private:
    int cur;
    int combinationLength;
    string characters;
};
上一篇下一篇

猜你喜欢

热点阅读