【LeetCode算法系列题解】第46~50题

这篇具有很好参考价值的文章主要介绍了【LeetCode算法系列题解】第46~50题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

LeetCode 46. 全排列(中等)

【题目描述】

给定一个不含重复数字的数组 nums,返回其所有可能的全排列。你可以按任意顺序返回答案。

【示例1】

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

【示例2】

输入:nums = [0,1]
输出:[[0,1],[1,0]]

【示例3】

输入:nums = [1]
输出:[[1]]

【提示】

1 ≤ n u m s . l e n g t h ≤ 6 1\le nums.length\le 6 1nums.length6
− 10 ≤ n u m s [ i ] ≤ 10 -10\le nums[i]\le 10 10nums[i]10
nums 中的所有整数互不相同

【分析】


全排列的裸题,DFS 入门题,不需要过多讲解了,由于题目保证每个数互不相同,因此可以用一个整数的二进制中的每一位表示某个数是否已被使用,省去开标记数组的额外空间开销。

当然,用 next_permutation 函数也是可以秒杀的,不过面试肯定还是要会手搓~


【代码】文章来源地址https://www.toymoban.com/news/detail-693319.html

next_permutation 函数实现】

class Solution {
public:
    vector<vector<int>> res;

    vector<vector<int>> permute(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        do {
            res.push_back(nums);
        } while (next_permutation(nums.begin(), nums.end()));
        return res;
    }
};

【DFS 实现】

class Solution {
public:
    vector<vector<int>> res;
    vector<int> v;

    vector<vector<int>> permute(vector<int>& nums) {
        dfs(nums, 0, 0);
        return res;
    }

    void dfs(vector<int>& nums, int u, int state)  // state二进制的第i位表示i是否已被使用
    {
        if (u == nums.size()) { res.push_back(v); return; }
        for (int i = 0; i < nums.size(); i++)
            if (!(state >> nums[i] + 10 & 1))  // 判断state的第i位是否为1,注意将nums[i]映射成0~20
            {
                v.push_back(nums[i]);
                dfs(nums, u + 1, state | 1 << nums[i] + 10);
                v.pop_back();
            }
    }
};

LeetCode 47. 全排列 II(中等)

【题目描述】

给定一个可包含重复数字的序列 nums,按任意顺序返回所有不重复的全排列。

【示例1】

输入:nums = [1,1,2]
输出:[[1,1,2],[1,2,1],[2,1,1]]

【示例2】

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

【提示】

1 ≤ n u m s . l e n g t h ≤ 8 1\le nums.length\le 8 1nums.length8
− 10 ≤ n u m s [ i ] ≤ 10 -10\le nums[i]\le 10 10nums[i]10

【分析】


这一题和上一题的差别在于数字可能有重复,因此需要考虑如何控制搜索出来的序列不会重复。对于相同的数,我们应该规定他们的顺序,比如统一按升序排列或者降序排列,这样相同的数的排列就只会有一种对应关系。

如何实现这一操作呢?我们先对数组进行排序,我们要保证答案中相同数的相对位置和原始数组一样,因此我们在枚举每个数 nums[i] 的时候,如果 nums[i] == nums[i - 1],且 nums[i - 1] 还没有被使用,那么 nums[i] 也不能使用。我们在这题中使用 state 二进制的第 i i i 位表示 nums[i] 是否被使用。


【代码】

class Solution {
public:
    vector<vector<int>> res;
    vector<int> v;

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());  // 先排好序
        dfs(nums, 0, 0);
        return res;
    }

    void dfs(vector<int>& nums, int u, int state)
    {
        if (u == nums.size()) { res.push_back(v); return; }
        for (int i = 0; i < nums.size(); i++)
            // 如果当前数和前一个数相等但是前一个数没被用过那么当前数也不能用
            if (i && nums[i] == nums[i - 1] && !(state >> i - 1 & 1)) continue;
            else if (!(state >> i & 1))  // 判断第i个数是否被使用
            {
                v.push_back(nums[i]);
                dfs(nums, u + 1, state | 1 << i);
                v.pop_back();
            }
    }
};

LeetCode 48. 旋转图像(中等)

【题目描述】

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

【示例1】

【LeetCode算法系列题解】第46~50题,LeetCode,算法,leetcode,深度优先,c++,学习

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

【示例2】

【LeetCode算法系列题解】第46~50题,LeetCode,算法,leetcode,深度优先,c++,学习

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

【提示】

n = = m a t r i x . l e n g t h = = m a t r i x [ i ] . l e n g t h n == matrix.length == matrix[i].length n==matrix.length==matrix[i].length
1 ≤ n ≤ 20 1\le n\le 20 1n20
− 1000 ≤ m a t r i x [ i ] [ j ] ≤ 1000 -1000\le matrix[i][j]\le 1000 1000matrix[i][j]1000

【分析】


我们先给出一个变换过程的例子:

1 2 3      1 4 7      7 4 1
4 5 6  =>  2 5 8  =>  8 5 2
7 8 9      3 6 9      9 6 3

该过程很简单,但是没有接触过类似题目的话确实很难想出来,首先沿着主对角线进行翻转,然后沿着列的中轴进行翻转即可。


【代码】

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        // 沿对角线翻转
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++)
                swap(matrix[i][j], matrix[j][i]);
        // 沿列中轴线翻转
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n >> 1; j++)
                swap(matrix[i][j], matrix[i][n - 1 - j]);
    }
};

LeetCode 49. 字母异位词分组(中等)

【题目描述】

给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。
字母异位词是由重新排列源单词的所有字母得到的一个新单词。

【示例1】

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

【示例2】

输入: strs = [""]
输出: [[""]]

【示例3】

输入: strs = ["a"]
输出: [["a"]]

【提示】

1 ≤ s t r s . l e n g t h ≤ 1 0 4 1\le strs.length\le 10^4 1strs.length104
0 ≤ s t r s [ i ] . l e n g t h ≤ 100 0\le strs[i].length\le 100 0strs[i].length100
strs[i] 仅包含小写字母

【分析】


我们可以将每个字符串按字典序排序,这样如果两个字符串所含的字符相同那么排序后的字符串一定也相同,然后我们再用一个哈希表记录每类字符串即可。


【代码】

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        unordered_map<string, int> st;  // 记录每一类的下标
        int idx = 0;
        for (auto s: strs)
        {
            string t = s;
            sort(t.begin(), t.end());
            if (!st[t]) st[t] = ++idx, res.push_back(vector<string> { s });
            else res[st[t] - 1].push_back(s);  // 注意vector中下标从0开始
        }
        return res;
    }
};

LeetCode 50. Pow(x, n)(中等)

【题目描述】

实现 pow(x, n),即计算 x 的整数 n 次幂函数(即, x n x^n xn)。

【示例1】

输入:x = 2.00000, n = 10
输出:1024.00000

【示例2】

输入:x = 2.10000, n = 3
输出:9.26100

【示例3】

输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25

【提示】

− 100.0 < x < 100.0 -100.0 < x < 100.0 100.0<x<100.0
− 2 31 ≤ n ≤ 2 31 − 1 -2^{31}\le n\le 2^{31}-1 231n2311
n 是一个整数
要么 x 不为零,要么 n > 0
− 1 0 4 ≤ x n ≤ 1 0 4 -10^4\le x^n\le 10^4 104xn104

【分析】


快速幂裸题,统一将 n n n 转为非负数再求解,最后再根据 n n n 的正负修改结果即可( x − n = 1 x n x^{-n}=\frac {1}{x^n} xn=xn1)。注意如果 n n nINT_MIN 直接转换为正数会溢出,因此需要开 long long


【代码】

class Solution {
public:
    double myPow(double x, int n) {
        double res = 1;
        for (long long k = abs((long long)n); k; k >>= 1)
        {
            if (k & 1) res *= x;
            x *= x;
        }
        if (n < 0) res = 1 / res;
        return res;
    }
};

到了这里,关于【LeetCode算法系列题解】第46~50题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python | Leetcode Python题解之第50题Pow(x,n)

    题目: 题解:

    2024年04月28日
    浏览(41)
  • 【深度优先】【广度优先】Leetcode 104 二叉树的最大深度 Leetcode 111 二叉树的最小深度 Leetcode 110 平衡二叉树

    二叉树节点的深度: 指从根节点到该节点的最长简单路径边的条数或者节点数 (取决于深度从0开始还是从1开始) 二叉树节点的高度: 指从该节点到叶子节点的最长简单路径边的条数后者节点数 (取决于高度从0开始还是从1开始) 【前序求的是深度,后序求的是高度】 -

    2024年02月19日
    浏览(53)
  • leetcode46. 全排列(回溯算法-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/permutations 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例 2: 输入:nums = [0,1] 输出:[[0,1],[1,0]]

    2024年02月11日
    浏览(42)
  • LeetCode-200. 岛屿数量【深度优先搜索 广度优先搜索 并查集 数组 矩阵】

    给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均被水包围。 示例 1: 输入:grid = [ [“1”,“1”,“1”,“

    2024年04月14日
    浏览(40)
  • 【快乐手撕LeetCode题解系列】——移除元素

        😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主! 😘博主小留言:哈喽! 😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不

    2023年04月15日
    浏览(37)
  • 【快乐手撕LeetCode题解系列】——消失的数字

        😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主! 😘博主小留言:哈喽! 😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不

    2024年02月01日
    浏览(33)
  • 每天一道leetcode:797. 所有可能的路径(图论&中等&深度优先遍历)

    给你一个有 n 个节点的 有向无环图(DAG) ,请你找出所有从节点 0 到节点 n-1 的路径并输出( 不要求按特定顺序 ) graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j] 存在一条有向边)。 n == graph.length 2 = n = 15 0 = graph[i][j] n graph[i][j] != i (即不存

    2024年02月12日
    浏览(65)
  • ※【回溯】【深度优先前序】Leetcode 257. 二叉树的所有路径

    ---------------🎈🎈257. 二叉树的所有路径 题目链接🎈🎈------------------- 时间复杂度O(N) 空间复杂度O(N) 深度优先遍历 添加了 StringBulider 替代字符串拼接提升效率 toString() 转化为String .append() 添加元素 时间复杂度O(N) 空间复杂度O(N)

    2024年02月20日
    浏览(38)
  • Leetcode题解-算法-动态规划(python版)

    1.1 爬楼梯 70. 爬楼梯(Easy) 走n阶楼梯的方法有两种,1、先走 1 级台阶,再走 n-1 级台阶;2、先走 2 级台阶,再走 n-2 级台阶 f(n) = f(n-1) + f(n-2) 1.2 强盗抢劫 198. 打家劫舍(Medium) 每个房间财产为 nums[0]……nums[n-1]。 假设 0 至 x 间房获得的最大财产为 f(x)。 f(x) = max(f(x-1),f(x-2)+nums[

    2024年02月03日
    浏览(51)
  • LeetCode算法题解(动态规划)|LeetCode343. 整数拆分、LeetCode96. 不同的二叉搜索树

    题目链接:343. 整数拆分 题目描述: 给定一个正整数  n  ,将其拆分为  k  个  正整数  的和(  k = 2  ),并使这些整数的乘积最大化。 返回  你可以获得的最大乘积  。 示例 1: 示例 2: 提示: 2 = n = 58 算法分析: 定义dp数组及下标含义: dp[i]表述正整数i拆分成k个正整数

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包