Leetcode:Combinations

来源:互联网 发布:港台频道直播软件 编辑:程序博客网 时间:2024/06/05 07:43

1.Problem

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.

For example,
If n = 4 and k = 2, a solution is:

[  [2,4],  [3,4],  [2,3],  [1,2],  [1,3],  [1,4],]

2.Pre-Thought

采用01反转法,可解决该问题。(请参考:http://www.360doc.com/content/10/1102/16/4095212_66011065.shtml)

3.Difficulty

3.1Runtime ErrorLast executed input:

出现该问题的原因是未考虑while循环的终止条件,使得迭代器溢出。这是一个很深刻的教训!!!

            // 寻找反转位置            // !!!谨记:迭代器的值最大为end(),要及时跳出循环            while(!(pre == 1 && cur == 0))            {                pre = cur;                cur = *it++;                first++;                 if(!is_first)                    first_one++;                if(cur == 1)                {                    one_num++;                                       if(!is_first)                        is_first = true;                }                if(it == st.end())                     break;            }

3.2扫描结束的终止条件


            // 如果first = n,直接退出            if(first_one != n-k+1)

4.Coding

<pre name="code" class="cpp">#include<iostream>#include<vector>using namespace std;class Solution{public:    vector<vector<int> > combine(int n, int k)    {        // 对10集合和结果集合进行初始化        vector<int> sub_result;        vector<vector<int> > result;        vector<int> st(k, 1);        st.insert(st.end(), n - k, 0);        int i;        // 对每一次扫描所需的变量进行声明        int pre = -1;// 扫描的前一个数        int cur = -1;// 当前扫描的数                int first = -1;// 记录第一个10的位置,这是10反转的位置        int first_one = 1;// 记录第一个1的位置        bool is_first = false;// 判断1是否是第一次出现        int num = 0;// 输出当前的数        int k_num = 0;// 记录1的个数        int one_num = 0;// 记录10组合前面1的个数        int zero_num = 0;// 记录10组合前面0的个数        vector<int>::iterator it;        vector<int>::iterator b;        vector<int>::iterator e;         // 如果k=1,分别输出1,2,.....n即可        if(k == 1)        {            for(i = 1; i <= n; i++)            {                sub_result.push_back(i);                result.push_back(sub_result);                sub_result.clear();            }            return result;        }        // 如果n=k,直接输出1,2......n即可        if(n == k)        {            for(i = 1; i <= n; i++)            {                sub_result.push_back(i);            }            result.push_back(sub_result);            sub_result.clear();            return result;        }         // 初始化状态,输出1,2,3......k        for(i = 1; i <= k; i++)        {            sub_result.push_back(i);        }        result.push_back(sub_result);        do         {            // 对每一次内层循环进行初始化            sub_result.clear();            pre = -1;             it = st.begin();            cur = *it++;// 从第一个数开始扫描            first = 0;            first_one = 1;            is_first = false;            one_num = 0;            zero_num = 0;            if(cur == 1)            {                one_num = 1;                first_one = 1;                is_first = true;            }                        // 寻找反转位置            // !!!谨记:迭代器的值最大为end(),要及时跳出循环            while(!(pre == 1 && cur == 0))            {                pre = cur;                cur = *it++;                first++;                 if(!is_first)                    first_one++;                if(cur == 1)                {                    one_num++;                                       if(!is_first)                        is_first = true;                }                if(it == st.end())                     break;            }                      // 如果first = n,直接退出            if(first_one != n-k+1)            {                // 反转                *(it - 1) = 1;                *(it - 2) = 0;                // 将10组合前面的1全部置前                one_num--;// 01组合前面1的个数                zero_num = first - one_num - 1;// 01组合前面0的个数                b = st.begin();                e = it - 2;                st.erase(b, e);// 先删除10组合前面的所有数                b = st.begin();                st.insert(b, zero_num, 0);// 在10组合前面先插入zero_num个0                b = st.begin();// 记得每一次更新首元素时,要更新迭代器                st.insert(b, one_num, 1);// 在10组合前面再插入one_num个1                // 对10元素集合进行遍历,将1所在位置的数存入sub_result集合中                it = st.begin();                num = 0;                k_num = 0;                while(k_num != k)                {                    num++;                    if(*it++ == 1)                    {                        k_num++;                        sub_result.push_back(num);                    }                }                result.push_back(sub_result);            }        }while(first_one != n-k+1);        return result;    }};int main(){    int n = 4;    int k = 2;    vector<vector<int> > result;    Solution sol;    result = sol.combine(n, k);    vector<vector<int> >::iterator it1 = result.begin();        while(it1 != result.end())    {        vector<int> temp = *it1++;        vector<int>::iterator it2 = temp.begin();        while(it2 != temp.end())        {            cout<<*it2++<<" ";        }        cout<<"Lenght:"<<temp.size()<<endl;    }    cout<<"Result:"<<result.size()<<endl;    return 0;}







0 0
原创粉丝点击