• 1286. Iterator for Combination


    问题:

    设计一个组合指针类,通过给定组合元素characters,要求构成组合的大小combinationLength,实现以下方法

    构造方法:CombinationIterator(string characters, int combinationLength)

    返回下一个组合:next() 

    是否存在下一个组合:hasNext() 

    Example 1:
    Input
    ["CombinationIterator", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
    [["abc", 2], [], [], [], [], [], []]
    Output
    [null, "ab", true, "ac", true, "bc", false]
    
    Explanation
    CombinationIterator itr = new CombinationIterator("abc", 2);
    itr.next();    // return "ab"
    itr.hasNext(); // return True
    itr.next();    // return "ac"
    itr.hasNext(); // return True
    itr.next();    // return "bc"
    itr.hasNext(); // return False
     
    
    Constraints:
    1 <= combinationLength <= characters.length <= 15
    All the characters of characters are unique.
    At most 104 calls will be made to next and hasNext.
    It's guaranteed that all calls of the function next are valid.
    

      

    解法:

    保存构造体:vector<string>

    解法一:Backtracking(回溯算法)

    • 状态:到当前位置为止,构成的组合path。
    • 选择:从给定组合元素的第pos个开始(前面的元素,path已经选择过),到最后一个都可选择。
    • 递归退出条件:path.size=combinationLength(要求的组合大小)

    代码参考:

     1 class CombinationIterator {
     2 public:
     3     vector<string> comb;
     4     int itr;
     5     void dfs(string characters, int combinationLength, int pos, string path) {
     6         if(combinationLength == path.length()) {
     7             comb.push_back(path);
     8             return;
     9         }
    10         for(int i=pos; i<characters.size(); i++) {
    11             dfs(characters, combinationLength, i+1, path+characters[i]);
    12         }
    13     }
    14     CombinationIterator(string characters, int combinationLength) {
    15         itr=0;
    16         dfs(characters, combinationLength, 0, "");
    17     }
    18     
    19     string next() {
    20         return itr!=comb.size()?comb[itr++]:"";
    21     }
    22     
    23     bool hasNext() {
    24         return itr!=comb.size();
    25     }
    26 };
    27 
    28 /**
    29  * Your CombinationIterator object will be instantiated and called as such:
    30  * CombinationIterator* obj = new CombinationIterator(characters, combinationLength);
    31  * string param_1 = obj->next();
    32  * bool param_2 = obj->hasNext();
    33  */

    解法二:

    保存构造体:set<string>(由题意,有顺序要求)

    bit组合法:

    每个元素代表一个bit位,选择表示1,不选表示0

    那么,题意中要求选择长度combinationLength的元素构成组合,即:选择所有元素构成bit中含有2个1的组合。

    再将这两个1对应的元素拿出来,拼成解,加入解list中。

    参考:LeetCode Thought

    解法关联

    Suppose Input string - "abc" and combinationLength =2
        now mask = 8 which is nothing but 2 power length of of "abc"
        now Itarate from 1 to 8 
    
       Num             bit_rep           no_of_set_bit       a   b   c            hold_set
        1               0 0 1                 1              0   0   1              nothing   <= because combinationLength != no_of_set_bit
        2               0 1 0                 1              0   1   0              same case like upper one
        3               0 1 1                 2              0   1   1              "bc" <= combinationLength ==no_of
        4               1 0 0                 1              1   0   0              nothing
        5               1 0 1                 2              1   0   1               "ac"
        6               1 1 0                 2              1   1   0               "ab"
        7               1 1 1                 3              1   1   1              nothing <= because combinationLength != no_of_set_bit
    
        return that set in lexi order ["ab","ac","bc"]
       
    Now We Done Our Main Work
    

      

    代码参考:

     1 class CombinationIterator {
     2 public:
     3     //vector<string> comb;
     4     set<string> comb;
     5     //int itr;
     6     set <string> :: iterator itr;
     7     /*void dfs(string characters, int combinationLength, int pos, string path) {
     8         if(combinationLength == path.length()) {
     9             comb.push_back(path);
    10             return;
    11         }
    12         for(int i=pos; i<characters.size(); i++) {
    13             dfs(characters, combinationLength, i+1, path+characters[i]);
    14         }
    15     }*/
    16     void creatcomb(string s, int len) {
    17         int maxn = 1<<s.length();
    18         for(int cmb=1; cmb<maxn; cmb++) {
    19             //count the num of 1:
    20             if(__builtin_popcount(cmb)!=len) continue;
    21             string newcomb;
    22             //the bit 1 in cmb means the alphbet in s would be selected.
    23             for(int i=cmb, idx=0; i>0; i>>=1, idx++) {
    24                 if(i&1) newcomb+=s[idx];
    25             }
    26             comb.insert(newcomb);
    27         }
    28         return;
    29     }
    30     CombinationIterator(string characters, int combinationLength) {
    31         //itr=0;
    32         creatcomb(characters, combinationLength);
    33         itr=comb.begin();
    34         //dfs(characters, combinationLength, 0, "");
    35     }
    36     
    37     string next() {
    38         return itr!=comb.end()?*itr++:"";
    39     }
    40     
    41     bool hasNext() {
    42         return itr!=comb.end();
    43     }
    44 };
    45 
    46 /**
    47  * Your CombinationIterator object will be instantiated and called as such:
    48  * CombinationIterator* obj = new CombinationIterator(characters, combinationLength);
    49  * string param_1 = obj->next();
    50  * bool param_2 = obj->hasNext();
    51  */
  • 相关阅读:
    假如
    Find the peace with yourself
    Sep 15th 2018
    Sep 10th 2018
    third party sales process 继续说
    成功设置open live writer
    sublime text2 基本配置及结合Python 环境
    Compmgmtlauncher.exe问题解决方法
    nginx 代理服务器
    vmware之linux不重启添加虚拟硬盘
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14349890.html
Copyright © 2020-2023  润新知