Leetcode permutation 系列

关于permutation的讲解,请参见http://blog.csdn.net/xuqingict/article/details/24840183

下列题目的讲解均是基于上面的文章:

题1:

Next Permutation

Total Accepted: 8066 Total
Submissions: 32493My Submissions

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3 → 1,3,2

3,2,1 → 1,2,3

1,1,5 → 1,5,1

给定一个permutation,直接求出下一个:

class Solution {
public:
    void nextPermutation(vector<int> &num) {
        typedef vector<int>::iterator iter;
        iter beg = num.begin(), end = num.end();
        if( beg == end || beg + 1 == end)return;

        iter right = end;
        --right;
        for(;;)
        {
            iter left = right;
            --left;

            if(*left < *right)
            {
                iter k = end;
                while(!(*left < *--k)){}
                iter_swap(left, k);
                reverse(right,end);
                return;
            }
            --right;
            if(right == beg)
            {
                reverse(beg, end);
                return;
            }
        }
    }
};

题2:

Permutations

Total Accepted: 12960 Total
Submissions: 42049My Submissions

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].

返回 所有的permutation

class Solution {
private:
typedef vector<int>::iterator iter;
bool helper(iter first, iter last)
{
    if(first == last) return false;

    if(first + 1 == last) return false;

    iter j = last;
    --j;

    while(1)
    {
        iter i = j;
        --i;
        //find a[i] < a[j] and they are adjacent
        if(*i < *j)
        {
            iter k = last;
            while(!(*i < *--k)){}
            std::swap(*i,*k);
            std::reverse(j,last);
            return true;
        }
        --j;
        //no such a[i] < a[i+1] pair found
        if( j == first)
        {
            //restore the first of the permutation
            std::reverse(first, last);
            return false;
        }
    }

}
public:
    vector<vector<int> > permute(vector<int> &num) {
        vector<vector<int> > ret;
        if(num.empty())return ret;

        iter beg = num.begin(), end = num.end();

        if(beg + 1 == end)
        {
            ret.push_back(num);
            return ret;
        }
        sort(beg,end); //首先必须sort!!!!

        do{
            ret.push_back(num);
        }while(helper(beg, end));

        return ret;
    }
};

题3:

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,

[1,1,2] have the following unique permutations:

[1,1,2][1,2,1],
and [2,1,1].

有重复元素的permutation,使用set结构来存储结果即可:

class Solution {
private:
typedef vector<int>::iterator iter;
bool permutation(iter beg, iter end)
{
    if(beg == end || beg + 1 == end)
    {
        return false;
    }
    iter right = end;
    --right;
    while(1)
    {
        iter left = right;
        --left;
        if(*left < *right)
        {
            iter k = end;
            while(!(*left < *--k)){}
            iter_swap(left,k);
            reverse(right,end);
            return true;
        }
        --right;
        if(right == beg)
        {
            reverse(beg,end);
            return false;
        }
    }
}

public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
        set<vector<int> > unique;
        sort(num.begin(), num.end());

        do
        {
            if(unique.count(num) == 0 )
                unique.insert(num);
        }while(permutation(num.begin(),num.end()));

        vector<vector<int> > ret(unique.begin(), unique.end());

        /*for(set<vector<int> >::iterator it = unique.begin();
        it != unique.end() ; ++it)
        {
            ret.push_back(*it);
        }*/

        return ret;
    }
};

题4 : 给出第k-th个permutation:

Permutation Sequence

Total Accepted: 6704 Total
Submissions: 31386My Submissions

The set [1,2,3,…,n] contains
a total of n! unique permutations.

By listing and labeling all of the permutations in order,

We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation
sequence.

Note: Given n will be between 1 and 9 inclusive.

解题思路:

首先,假设  n = 3, k = 4 , 我们可以得到上述的编码,可以发现,前 (n-1)!个元素是以  1  开头的,,第二组 (n-1)!的元素是以2开头的,那么我们就可以有

k = 4 = 2*2! + 0* 1! + 0*0!,那么该串中的字符应该是第2个,第0个,以及第0个字符,这里请注意,每一步的原始的元素集合是在减少1
的,比如;

第2个意味着 “123”的第2个,为‘3’, 那么此时的串变为 “12”

第0个意味着 “12”的第0个, 为 ‘1’,那么此时的串变为 “2”

第0个意味着 “2”的第0个,为 ‘2’, 那么此时串为空,结束,那么结果即为 “312”。

但是我们发现现在求的 “312”实际上是第5个(因为结果是从1开始的),因此只需要在计算之前将 k减一即可。也就是说在k之前一共有  k-1 个permutation,因此代码为:

class Solution {
public:
    string getPermutation(int n, int k)
    {
        string str;
        for(int i = 1 ; i <= n ; ++i)
            str += (‘0‘ + i);

        string ret;

        int base = 1;
        for(int i = n-1 ; i >= 1 ; --i)
        {
            base *= i;
        }

        --k;
        int i = n-1;
        while(i > 0 && k > 0) // iterate (n-1) times
        {
            int pos = k/base;
            k = k % base;
            ret += str[pos];
            str.erase(pos,1);
            base /= i;
            --i;
        }

        while(!str.empty())
        {
            ret += str[0];
            str.erase(0,1);
            --i;
        }
        return ret;

    }
};

上述permutation的题目,比较函数默认为less,如果为greater是同样的道理。

Leetcode permutation 系列,布布扣,bubuko.com

时间: 2024-12-15 01:35:42

Leetcode permutation 系列的相关文章

leetcode:permutation系列

一.Next Permutation: 给出一个数字排列的序列,返回按照升序排序的下一个序列.如果当前已经是最高的序列,则返回最低的序列,相当于一个轮回了. 原题:Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearra

LeetCode: Permutation Sequcence 题解

The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order,We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "3

【Leetcode长征系列】Letter Combinations of a Phone Number

原题: Given a digit string, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. Input:Digit string "23" Output: ["ad", "ae"

【Leetcode长征系列】Merge k Sorted Lists

原题: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:两条两条地合并.时间复杂度为O(n),n为所有链表节点和. 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) :

[LeetCode蠕动系列]Sort List

这题前一阵子就看到了,一直没时间做,昨晚睡前想了想,要求n*log(n)以内的时间复杂度,第一时间想到的就是归并.快排和希尔排序(注:希尔排序时间为O(n^1.3),在数据量大于2的情况下小于n*log(n)),个人以为,链表的特性更适合归并,所以采用归并排序,实现的merge代码如下: public static ListNode merge(ListNode rhead, ListNode lhead) { ListNode head = null; if (rhead.val <= lhe

LeetCode: Permutation Sequence [059]

[题目] The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" &

【Leetcode长征系列】Construct Binary Tree from Inorder and Postorder Traversal

原题: Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 思路:和上一题一样,后续我们可以通过最后一个值得到根的值,同样可以通过定位根的值得到左右子树的子集,递归求解即可. 代码: /** * Definition for binary tree * struct Tre

[leetcode]Permutation Sequence @ Python

原题地址:https://oj.leetcode.com/submissions/detail/5341904/ 题意: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order,We get the following sequence (ie, for n = 3): "123" "132&

【Leetcode长征系列】Single Number II

原题: Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 思路: 用一个32位的数组存每一位bit值之后.得到答案后每一位除