刷题46. Permutations

一、题目说明

题目是46. Permutations,给一组各不相同的数,求其所有的排列组合。难度是Medium

二、我的解答

这个题目,前面遇到过类似的。回溯法(树的深度优先算法),或者根据如下求解:

刷题31. Next Permutation

我考虑可以用dp做,写了一个上午,理论我就不说了,自己看代码:

#include<iostream>
#include<vector>
#include<unordered_map>

using namespace std;
class Solution{
    public:
        vector<vector<int>> permute(vector<int>& nums) {
            vector<vector<int>> res;
            vector<vector<int>> next;

            unordered_map<int,vector<vector<int>>> dp;
            vector<int> cur;

            if(nums.empty()) return res;

            cur.push_back(nums[0]);
            res.push_back(cur);
            dp[1] = res;
            int currLength = 2;
            for(int j=1;j<nums.size();j++){
                res = dp[j];
                next.clear();

                for(int k=0;k<currLength;k++){
                    cur.clear();
                    cur.resize(j+1);

                    for(int m=0;m<res.size();m++){
                        cur[k] = nums[j];
                        int t1=0,t2=0;
                        while(t2<res[m].size()){
                            if(cur[t1]!=nums[j]){
                                cur[t1] = res[m][t2];
                            }else{
                                ++t1;
                                cur[t1] = res[m][t2];
                            }
                            t1++;
                            t2++;
                        }

                        next.push_back(cur);

                        cur.clear();
                        cur.resize(j+1);
                    }
                }                                       

                currLength++;
                dp[j+1] = next;
            }
            return dp[nums.size()];
        }
};
int main(){
    Solution s;
    vector<int> nums = {1,2,3,4};
    vector<vector<int>> r = s.permute(nums);
    for(int i=0;i<r.size();i++){
        for(int j=0;j<r[i].size();j++){
            cout<<r[i][j]<<" ";
        }
        cout<<"\n";
    }

    return 0;
}

性能如下:

Runtime: 8 ms, faster than 98.85% of C++ online submissions for Permutations.
Memory Usage: 9.5 MB, less than 46.27% of C++ online submissions for Permutations.

三、优化措施

dp算法,是按照空间换时间的,所以时间还可以,空间就差了点。

下面是回溯算法的代码,可读性好多了:

class Solution{
    private:
        vector<vector<int>> result;
        vector<int> path;
        vector<bool> used;
    public:
        //枚举每个位置放哪个数
        void dfs(const vector<int>&nums,int pos){
            if(pos == nums.size()){
                result.push_back(path);
                return;
            }
            for(int i=0;i<nums.size();i++){
                if(!used[i]){
                    path.push_back(nums[i]);
                    used[i] = true;
                    dfs(nums,pos+1);
                    used[i] = false;
                    path.pop_back();
                }
            }
        }
        vector<vector<int>> permute(vector<int>& nums) {
            if(nums.empty()){
                return result;
            }

            used.resize(nums.size());
            dfs(nums,0);
            return result;
        }
};

原文地址:https://www.cnblogs.com/siweihz/p/12245079.html

时间: 2024-12-16 14:01:56

刷题46. Permutations的相关文章

【leetcode刷题笔记】Permutations II

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差不多,只是这次会有重复的元素,如下图所示,如果只用DFS的话就会产生重复的排列: 上

leetcode 刷题之路 77 Permutations II

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]. Permutations 的升级版,依旧是全排列问题,但是序列中可能会出现重复数字. 思路:采用字典序的非递归方

COGS2642 / Bzoj4590 [Shoi2015]自动刷题机

Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 906  Solved: 321 Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代码. B.心情不好,删掉了之前写的y行代码.(如果y大于当前代码长度则相当于全部删除.) 对于每

【leetcode刷题笔记】Max Points on a Line

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. 题解: 思路比较简单,每条直线都可以表示为y=kx+b,所以对于任意三点,如果它们共线,那么它们中任意两点的斜率都相等. 所以就遍历points数组,对其中的每一个元素计算它和位于它后面的数组元素的斜率并保存在一个hashmap中. 这个hashmap的键就是两点构成直线的斜率,值就是和当前元素po

【leetcode刷题笔记】Sort List

Sort a linked list in O(n log n) time using constant space complexity. 题解:实现一个链表的归并排序即可.主要分为三部分: 1.找到中点并返回的函数findMiddle; 2.归并函数merge; 3.排序函数sortList. 数组的findMiddle函数非常容易实现,链表就有一点tricky了.首先设置两个指针,一个slow初始化为head,一个fast初始化为head.next,然后slow一次走一步,fast一次走两

Leetcode刷题录之Two Sum

题意大概是给出一个数列num,和一个目标数target,然后要找出数列中的两个数,使得这两个数之和等于目标数,输出这两个数的下标值(从1开始算). 一个比较暴力的方法是用一个二重循环直接遍历序列,在第一重循环中找到a,在第二重循环中找到b,使得a+b=target,这种做法的时间复杂度是O(n^2), 提交时提示超时. 改进方法,先对数列num复制一个副本,然后对副本进行排序.在一重循环中找到a,接着对这个有序的副本进行二分查找,找到b= target-a,二分查找的 时间复杂度是O(logn)

BZOJ 4590: [Shoi2015]自动刷题机 二分答案

4590: [Shoi2015]自动刷题机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1056  Solved: 380[Submit][Status][Discuss] Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代

XDOJ 1020 ACMer去刷题吧(基础dp)

题目描述 刷题是每个ACMer必由之路,已知某oj上有n个题目,第i个题目小X能做对的概率为Pi(0<=Pi<=1,1<=i<=n) 求小X至少做对k道题的概率 输入 第一行输入一个正整数t,(t<=20),表示有t组测试样例. 第二行输入正整数n,k,(1<=n,k<=1000) 第三行输入n个小数,分别为Pi(1<=i<=n,0<=Pi<=1),表示小X做对第i个题目的概率. 输出 输出小X至少做对k道题的概率,并换行(保留4位小数)

BZOJ4590 自动刷题机

SHOI2015 Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模 块会有两种可能的结果: A.写了x行代码. B.心情不好,删掉了之前写的y行代码.(如果y大于当前代码长度则相当于全部删除.) 对于每个OJ所有题目,存在某个固定的长度n>0.一旦自动刷题机在某秒结束时积累了大于等于n行的代码,它就会 自动提交并