牛客刷题日记【没有重复项数字的全排列|有重复项数字的全排列|岛屿数量】

BM55 没有重复项数字的全排列

给出一组数字,返回该组数字的所有排列

例如:

[1,2,3]的所有排列如下
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)

数据范围:数字个数 0<n≤60<n≤6

要求:空间复杂度 O(n!)O(n!) ,时间复杂度 O(n!)O(n!)

思考:

首先,这道题目的时间复杂度要求和n的取值范围是可以打暴力的

正常的题解思路是用回溯搜这个数组的所有元素排列

在搜索过程中要明确这个位置的元素是否被添加过了,如果被添加过则跳过

代码:

暴力(只写了一部分……)

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param num int整型vector 
     * @return int整型vector<vector<>>
     */
    vector<vector<int> > permute(vector<int>& num) {
        // write code here
        vector<vector<int> > res;

        if (num.size() == 1)
        if (num.size() == 2)

        if (num.size() == 3)
        for (int i = 0;i < num.size();i++)  for (int j = 0;j < num.size();j++)  for (int k = 0;k < num.size();k++)
        {   
            if (i == j || i == k || j == k) continue;
            vector <int> tmp;
            tmp.push_back(num[i]);
            tmp.push_back(num[j]);
            tmp.push_back(num[k]);

            res.push_back(tmp);
        }
        if (num.size() == 4)
        if (num.size() == 5)
        if (num.size() == 6)

        return res;
    }
};

递归回溯

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param num int整型vector 
     * @return int整型vector<vector<>>
     */
    
    vector<vector<int> > res;
    void dfx(vector<int>& num, vector<int>& cur, vector<int>& pos) {
        if (cur.size() == num.size()) 
        {
            res.push_back(cur);
            return;
        }

        for (int i = 0;i < num.size();i++) {
            for (int j = 0;j < pos.size();j++)
                std::cout << pos[j] << " ";
            std::cout << endl;

            bool flag = false;
            for (int j = 0;j < pos.size();j++) if (i == pos[j]) flag = true;

            if (flag) continue;;

            vector<int> tmp = cur;
            tmp.push_back(num[i]);

            vector<int> poss = pos;
            poss.push_back(i);
            dfx(num, tmp, poss);
        }
    }
    
    vector<vector<int> > permute(vector<int>& num) {
        // write code here
        vector<int> d;
        vector<int> p;
        dfx(num,d,p);
        return res;
    }
};

BM56 有重复项数字的全排列

给出一组可能包含重复项的数字,返回该组数字的所有排列。结果以字典序升序排列。

数据范围: 0<n≤80<n≤8 ,数组中的值满足 −1≤val≤5−1≤val≤5

要求:空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!)

思考:

和上一题的思路基本相同,唯一不同点是上一题仅对位置进行了限制,即不能出现同一位置的排列

这次是对于同一层排序中,不能有重复元素出现,因此需要额外限制一下

在这里插入图片描述

左边是第一题的要求,右边是第二题新增的要求

代码:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param num int整型vector 
     * @return int整型vector<vector<>>
     */
    
    vector<vector<int> > res;
    void dfx(vector<int>& num, vector<int>& cur, vector<int>& pos) {
        if (cur.size() == num.size()) 
        {
            res.push_back(cur);
            return;
        }
        vector <int> c;

        for (int i = 0;i < num.size();i++) {
            bool flag = false;

            for (int j = 0;j < pos.size();j++)  if (i == pos[j]) flag = true;
            // 保证同层元素唯一
            for (int j = 0;j < c.size();j++)    if (num[i] == c[j]) flag = true;
            if (flag) continue;

            vector<int> tmp = cur;
            tmp.push_back(num[i]);

            vector<int> poss = pos;
            poss.push_back(i);
            c.push_back(num[i]);

            dfx(num, tmp, poss);
        }
    }
    
    vector<vector<int> > permuteUnique(vector<int>& num) {
        // write code here
        sort(num.begin(), num.end());

        vector<int> d;
        vector<int> p;
        dfx(num,d,p);
        
        return res;
    }
};

BM57 岛屿数量

给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。

岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。

思考:

这是一道基础的图论搜索题目,通过dfs将查询到新的陆地周围走过,让其不可再访问。

代码:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 判断岛屿数量
     * @param grid char字符型vector<vector<>> 
     * @return int整型
     */
    int res = 0;

    void dfx(vector<vector<char> >& grid,int x, int y) {
        if (grid[x][y] == '1') {
            grid[x][y] = '0'; 
            if (x + 1 < grid.size())    dfx(grid, x+1, y);
            if (x - 1 > -1)             dfx(grid, x-1, y);
            if (y + 1 < grid[x].size())    dfx(grid, x, y+1);
            if (y - 1 > -1)             dfx(grid, x, y-1);
        }
    }
    
    int solve(vector<vector<char> >& grid) {
        // write code here

        for (int i = 0;i < grid.size();i++) for (int j = 0;j < grid[i].size();j++)
        {
            if (grid[i][j] == '1') {
                res++;
                dfx(grid, i, j);
            }
        }

        return res;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值