leetcode | 排列相关题目

一、

567. Permutation in String


Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string's permutations is the substring of the second string.

Example 1:

Input:s1 = "ab" s2 = "eidbaooo"
Output:True
Explanation: s2 contains one permutation of s1 ("ba").

 

Example 2:

Input:s1= "ab" s2 = "eidboaoo"
Output: False

 

Note:

  1. The input strings only contain lower case letters.
  2. The length of both given strings is in range [1, 10,000].
class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        int len1 = s1.size();
        int len2 = s2.size();
        vector<int> vec1(26, 0);
        vector<int> vec2(26, 0);
        
        for(int i = 0; i != len1; ++i)
        {
            ++vec1[s1[i] - 'a'];
            ++vec2[s2[i] - 'a'];
        }
        if(vec1 == vec2)
            return true;
        for(int i = 0; i + len1 < len2; ++i)
        {
            --vec2[s2[i] - 'a'];
            ++vec2[s2[i+len1] - 'a'];
            if(vec1 == vec2)
                return true;
            
        }
        return false;
        
            
    }
};

二、

46. Permutations


Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        //递归法
        vector<vector<int>> res;
        vector<int> cur_vec;
        int n = nums.size();
       if(nums.empty()) 
           return res;
        dfs(res, cur_vec, nums, 0, n);
        return res;
       
    }
    //递归函数
    void dfs(vector<vector<int>> & res, vector<int> & cur_vec, vector<int> & nums, int begin, int n)
    {
        if(begin == n -1)
        {
            res.push_back(nums);
            return;
        }
        
        for(int i = begin; i != n; ++i)
        {
            //cur_vec.push_back(nums[i]);
            swap(nums[i], nums[begin]);
            dfs(res, cur_vec, nums,begin + 1, n);
            swap(nums[i], nums[begin]);
            //cur_vec.pop_back();
        }
    }
};

三、

31. Next Permutation


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 and use only constant 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

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        if(nums.empty())
            return;
        
        int n = nums.size();
        int index_swap_left = -1;//it is denote as the first  index that its value is low than its right value;
     
        //从后往前,寻找第一个非递增的数
        for(int i = n -1; i > 0; --i)
        {
            if(nums[i - 1] < nums[i])
            {
                index_swap_left = i - 1;//从右往左找到第一个就好了,break
                break;
            }
                
        }
        if(index_swap_left == -1)
        {
            reverse(nums.begin(), nums.end());
            return;            
        }
        
        int index_swap_right = -1;
        //从index——swap——left开始往右,第一个小于它的元素,将第一个小于它的元素左边那个稍大点的元素 赋值index——swap-right
        for(int i = index_swap_left + 1; i != n; ++i)
        {
            if(nums[index_swap_left] < nums[i])
            {
                index_swap_right = i;
            }
                
        }
        //cout << index_swap_left << " "<< index_swap_right;
        //交换两个元素
        swap(nums[index_swap_left], nums[index_swap_right]);
        reverse(nums.begin() + index_swap_left + 1, nums.end());
        return;
        
    }
};

四、

47. Permutations II


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

Example:

Input: [1,1,2]
Output:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]
class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> res;
        if(nums.empty())
            return res;
        int  n = nums.size();
        sort(nums.begin(), nums.end());//为了便于比较前后两个元素是否相同
        dfs(res, nums, 0, n);
        return res;
    }
    void dfs(vector<vector<int>> & res, vector<int> & nums, int begin, int n)
    {
        if(begin == n - 1)
        {
            res.push_back(nums);
            return;
        }
        for(int i = begin; i < n; ++i)
        {
            if(!findDuplicate(nums, begin, i))
            {
                swap(nums[i], nums[begin]);
                dfs(res, nums, begin +1, n);
                swap(nums[i], nums[begin]);
            }
         
        }
     }
    //判断是否重复的元素.当且仅当pos1与pos2)之间没有与pos2相同的的元素时候,此时才可以交换
    bool findDuplicate(vector<int> & nums, int pos1, int pos2)
    {
        for(; pos1 < pos2; ++pos1)
        {
            if(nums[pos1] == nums[pos2])
                return true;
            
        }
        return false;
    }
    
};
    

五、

60. Permutation Sequence


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 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.
  • Given k will be between 1 and n! inclusive.

Example 1:

Input: n = 3, k = 3
Output: "213"

Example 2:

Input: n = 4, k = 9
Output: "2314"
class Solution {
public:
    string getPermutation(int n, int k) {
        //观察规律可以得到如下的逐步迭代算法

        vector<int> nums(n);
        vector<int> Factorial(n);
        int res = 1;
        string result = "";

        for(int i = 0; i != n; ++i)
        {
            res *= (i + 1);
            Factorial[i] = res;
            nums[i] = i + 1;
        }
        // for(auto &i :nums)
        //     cout << i<< " ";
        // for(auto &i :Factorial)
        //     cout << i << " ";
        k = k -1;//注意第k个,实际上是从0开始的k-1个索引处
        for(int i = 1; i != n; ++i)
        {
            int index = k/Factorial[n - i - 1] ;//注意是 k/(n-1 )!->指向的是nums的索引
            ///cout << nums[index];
            result += to_string(nums[index]);
            nums.erase(nums.begin() + index);//一旦nums中某个索引找到后,直接删除
            //n = n -1;//此时的n-1 -> n 在Factorial[n-i-1]中体现
            k = k % Factorial[n - i- 1];//k%(n-1)!
        }
        result += to_string(nums[0]);//将最后一个加上
        return result;
            
    
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值