惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
Y
Y Combinator Blog
博客园_首页
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
Hugging Face - Blog
Hugging Face - Blog
宝玉的分享
宝玉的分享
B
Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
WordPress大学
WordPress大学
L
LangChain Blog
爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
博客园 - 聂微东
云风的 BLOG
云风的 BLOG
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Help Net Security

博客园 - 来自海边的一片云

Binary Tree Maximum Path Sum 解题注意 CodingTMD’s Reading List De Bruijn 序列生成 Word Ladder I ,II 解题思路 suduko及8皇后问题及相关问题的解题思路 leetcode Word Break II 解题思路 Search for a string in an infinite stream of input string. 内存管理 Clone Graph leetcode 开弓没有回头箭 combination sum leetcode Combinations leetcode 组合问题 word break leetcode LRU cache Leetcode 重新试着写blog SQL injection Fuzz testing XML库的解析效率 Init()
Permutations leetcode
来自海边的一片云 · 2014-02-10 · via 博客园 - 来自海边的一片云
Given a collection of numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].

排列问题,

直观的排列问题如{1,2,3} 当第一次位的1 确定的时候后,需要从2,3 里面进行全排列,然后得到 1,2,3 和,1,3,2。

因此得到一个算法,用一个flags 来记录这个数是否已经被用过。

如果已经选到第n个字符( level ==n) 那就把记录下的路径,加到输出结果里。

如果到level 还没有到字符串长度的时后,

     遍历flags数组,找到第一个没有用过的字符,把这个字符加到中间的结果里,然后在把该字符标记为用过,

      递归选level+1位置上的字符。

    当递归结束的时候,把该字符标记为可用。

//
//排列问题的解法,最基本的肯定是递归
//
    void getpermute(vector<int>& num, vector<vector<int>> &result, vector<int>& v, vector<bool>& flags, int level)
    {
        if(level == num.size())// end of 
        {
            result.push_back(v);
            return;
        }
        else
        {
            for( int k=0; k<num.size(); k++)
            {
                if(flags[k] == true) continue;
                
                v[level]= num[k];
                flags[k] = true;
                getpermute(num, result, v, flags, level+1);
                flags[k] = false;
            }
        }
    }
    
    vector<vector<int> > permute(vector<int> &num) {
        int len = num.size();
        vector<bool> flags(len);
        vector<vector<int>> result;
        vector<int> v(len);
        int level =0;
        
        getpermute(num, result, v, flags, level);
        
        return result;
    }

这个题目的变种还可以变成,给定字符集比如 {1,2,3,4} 让你找出所有长度为3的排列。

这个怎么做呢,其实很简单,就在上面的中止条件上改成当flags = targetlength,就中止。

思路还是不变,搞个flags 数组,

当目标排列字符串数组位置level = targetlength的时候就可以把结果输出了。

如果当目标字符串数组位置level 还没有到targetlength时候  

          遍历整个flags的数组,找到第一个没有用过的数

         标记这个数,

         把这个数放到中间结果里         

         递归选level+1位置上的字符。

         当递归结束的时候,把该字符标记为可用。

void getpermute(vector<int>& num, vector<vector<int>> &result, vector<int>& v, vector<bool>& flags, int level, int targetlength)
{
    if (level == targetlength)// end of 
    {
        result.push_back(v);
        return;
    }
    else
    {
        for (int k = 0; k<num.size(); k++)
        {
            if (flags[k] == true) continue;

            v[level]=num[k];
            flags[k] = true;
            getpermute(num, result, v, flags, level + 1, targetlength);
            flags[k] = false;
        }
    }
}

另外一种变种是目标集合里面包含重复的元素

一种简单的办法就是消耗空间的set,这样保证题目能做出来。

另外就要考虑如何保持消除重复,直觉关键还是在flags上。

BAXYZ

当处理X这个字符的时候,如果X==A而且A这字符已经处理过得情况下,原来的字符串变成了BAAYZ, 表明这个情况已经处理过了。 

   void getpermute(vector<int>& num, vector<vector<int>> &result, vector<int>& v, vector<bool>& flags, int level)
    {
        if(level == num.size())// end of 
        {
            result.push_back(v);
            return;
        }
        else
        {
            for( int k=0; k<num.size(); k++)
            {
                if(flags[k] == true || k!=0 && num[k-1]== num[k]&& flags[k-1]) continue; //当前这个字符和前面的字符一样,并且前面的那个字符已经用过了,
                v[level]= num[k];
                flags[k] = true;
                getpermute(num, result, v, flags, level+1);
                flags[k] = false;
            }
        }
    }
    
    vector<vector<int> > permuteUnique(vector<int> &num) {
        int len = num.size();
        vector<bool> flags(len);
        vector<vector<int>> result;
        vector<int> v(len);
        int level =0;
        sort(num.begin(), num.end());
        getpermute(num, result, v, flags, level);
        
        return result;
    }