LeetCode刷题记41-50

LeetCode 41. 缺失的第一个正数

题目类型

  1. 哈希表
  2. 技巧法

题目链接

https://leetcode.cn/problems/first-missing-positive/

思路

方法一(哈希表):

  1. nums 中每个元素放入哈希表中
  2. 从res = 1开始,每次查询一次hash.count(res)
  3. 如果存在,则res++
  4. 如果不存在,返回res,res为所求结果

方法二:

  1. 如果满足条件nums[i] >= 0 && nums[i] < n && nums[i] != i && nums[i] != nums[nums[i]]
  2. 遍历nums数组,每次将nums[i]元素放到相应的i位置

AC代码1

class Solution &#123;
public:
    int firstMissingPositive(vector<int>& nums) &#123;
        unordered_set<int> hash;
        for (auto x : nums)
        &#123;
            hash.insert(x);
        &#125;
        int res = 1;
        while (hash.count(res)) res ++; 

        return res;
    &#125;
&#125;;

AC代码2

class Solution &#123;
public:
    int firstMissingPositive(vector<int>& nums) &#123;
        int n = nums.size();
        if (!n) return 1;

        // 映射一下
        for (auto&x : nums)
            if (x != INT_MIN) x --;

        for (int i = 0; i < n; i ++)
        &#123;
            while (nums[i] >= 0 && nums[i] < n && nums[i] != i && nums[i] != nums[nums[i]])
            &#123;
                swap(nums[i], nums[nums[i]]);
            &#125;
        &#125;

        // 查询
        for (int i = 0; i < n; i ++)
        &#123;
            if (nums[i] != i)
                return i + 1;
        &#125;
        return n + 1;
    &#125;
&#125;;

LeetCode 42. 接雨水

题目类型

  1. 三次线性扫描法
  2. 单调栈

题目链接

https://www.acwing.com/activity/content/problem/content/2379/

思路

参考大佬的题解: https://www.acwing.com/solution/content/121/

方法一:

  1. 每个位置能接受的雨水取决于左边最大、右边最大和当前高度
  2. 即每个位置的接受雨水 = min(左边最大, 右边最大) - 当前位置的高度

方法二(单调栈):

  1. 考虑每个位置左边和右边第一个比自身不低的矩形,以及三个矩形构成的凹槽

AC代码1

class Solution &#123;
public:
    int trap(vector<int>& height) &#123;
        int n = height.size();
        int ans = 0;
        if (!n) return ans;
        // 每个位置能接受的雨水取决于左边最大、右边最大和当前高度
        // 即每个位置的接受雨水 = min(左边最大, 右边最大) - 当前位置的高度
        // 记录每个位置的左边最大 和 右边最大
        vector<int> left_max(n), right_max(n);

        // 寻找左边最大
        left_max[0] = height[0];
        for (int i = 1; i < n; i ++)
        &#123;
            left_max[i] = max(left_max[i - 1], height[i]);
        &#125;

        // 寻找右边最大
        right_max[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; i --)
        &#123;
            right_max[i] = max(right_max[i + 1], height[i]);
        &#125;

        // for (int i = 0; i < n; i ++) cout << left_max[i] << " ";
        // cout << endl;
        // for (int i = 0; i < n; i ++) cout << right_max[i] << " ";
        // cout << endl;

        // 计算接收雨水量
        for (int i = 0; i < n; i ++)
        &#123;
            ans += min(left_max[i], right_max[i]) - height[i];
        &#125;
        return ans;
    &#125;
&#125;;

AC代码2

class Solution &#123;
public:
    int trap(vector<int>& height) &#123;
        int n = height.size();
        stack<int> stk;

        int ans = 0;
        for (int i = 0; i < n; i ++)
        &#123;
            while (!stk.empty() && height[stk.top()] <= height[i])
            &#123;
                int top = stk.top();
                stk.pop();

                if (stk.empty()) break;
                ans += ( min(height[stk.top()], height[i]) - height[top] ) * (i - 1 - stk.top());
            &#125;
            stk.push(i);
        &#125;

        return ans;
    &#125;
&#125;;

LeetCode 43. 字符串相乘

题目类型

  1. 乘法运算

题目链接

https://leetcode.cn/problems/multiply-strings/

思路

参考算法基础高精度乘法算法:https://alexjakin.github.io/2022/05/18/jichusuanfapiangaojingduyunsuanbiji/

AC代码

class Solution &#123;
public:
    string multiply(string num1, string num2) &#123;
        int n = num1.size(), m = num2.size();
        vector<int> A;
        vector<int> B; 
        vector<int> C(n + m);

        for (int i = n - 1; i >= 0; i --) A.push_back(num1[i] - '0');
        for (int i = m - 1; i >= 0; i --) B.push_back(num2[i] - '0');

        for (int i = 0; i < n; i ++)
            for (int j = 0; j < m; j ++)
                C[i + j] += A[i] * B[j];

        for (int i = 0, t = 0; i < C.size(); i ++)
        &#123;
            t += C[i];
            C[i] = t % 10;
            t /= 10; 
        &#125;

        //去掉前导0
        int k = C.size() - 1;
        while (k && !C[k]) k --;

        string res;
        // C高位在后低位在前
        while (k >= 0) res += C[k --] + '0';
        return res;
    &#125;
&#125;;

LeetCode 44. 通配符匹配

题目类型

  1. 动态规划

题目链接

https://leetcode.cn/problems/wildcard-matching/

思路

参考大佬题解
https://www.acwing.com/solution/content/127/

AC代码

class Solution &#123;
public:
    bool isMatch(string s, string p) &#123;
        int n = s.size(), m = p.size();
        s = ' ' + s, p = ' ' + p;
        vector<vector<bool>> f(n + 1, vector<bool>(m + 1));

        f[0][0] = true;

        for (int i = 0; i <= n; i ++)
        &#123;
            for (int j = 1; j <= m; j ++)
            &#123;
                if (p[j] == '*')
                &#123;
                    f[i][j] = f[i][j - 1] || (i && f[i - 1][j]);
                &#125;
                else 
                &#123;
                    f[i][j] = (s[i] == p[j] || p[j] == '?') && i && f[i - 1][j - 1];
                &#125;
            &#125;
        &#125;

        return f[n][m];
    &#125;
&#125;;

LeetCode 45. 跳跃游戏 II

题目类型

  1. 贪心算法
  2. 数组

题目链接

https://leetcode.cn/problems/jump-game-ii/

思路

私以为这道题代码简单,难度不低
参考大佬题解:https://leetcode.cn/problems/jump-game-ii/solution/45-by-ikaruga/

AC代码1

class Solution &#123;
public:
    int jump(vector<int>& nums) &#123;
        int ans = 0;
        int start = 0;
        int end = 1;
        while (end < nums.size())
        &#123;
            int maxPos = 0;
            for (int i = start; i < end; i ++)
            &#123;
                maxPos = max(maxPos, i + nums[i]);
            &#125;
            // 更新下一次搜索位置
            start = end;
            end = maxPos + 1;
            ans ++;
        &#125;
        return ans;
    &#125;
&#125;;

AC代码2

class Solution &#123;
public:
    int jump(vector<int>& nums) &#123;
        int end = 0;
        int maxPos = 0;
        int ans = 0;
        for (int i = 0; i < nums.size() - 1; i ++)
        &#123;
            maxPos = max(maxPos, i + nums[i]);
            if (i == end)
            &#123;
                end = maxPos;
                ans ++;
            &#125;
        &#125;
        return ans;
    &#125;
&#125;;

LeetCode 46. 全排列

题目类型

  1. dfs

题目链接

https://leetcode.cn/problems/permutations/

思路

简单dfs问题,参考我之前一篇dfs相关文章,第一道例题类似题
https://alexjakin.github.io/2022/06/10/suanfajichupiandfshebfsjiqijingdianxiti/

AC代码

class Solution &#123;
public:
    int n;
    vector<vector<int>> ans;
    vector<int> path;
    vector<bool> st;

    vector<vector<int>> permute(vector<int>& nums) &#123;
        n = nums.size();
        path = vector<int> (n);
        st = vector<bool> (n);

        dfs(nums, 0);
        return ans;
    &#125;

    void dfs(vector<int> &nums, int u)
    &#123;
        if (u == n)
        &#123;
            ans.push_back(path);
            return ;
        &#125;

        for (int i = 0; i < n ; i ++)
        &#123;
            if (!st[i])
            &#123;
                st[i] = true;
                path[u] = nums[i];
                dfs(nums, u + 1);
                st[i] = false;
            &#125;
        &#125;
    &#125;
&#125;;

LeetCode 47. 全排列 II

题目类型

  1. dfs

题目链接

https://leetcode.cn/problems/permutations-ii/

思路

参考y总的题解
https://www.acwing.com/solution/content/126/

AC代码

class Solution &#123;
public:
    int n;
    vector<vector<int>> ans;
    vector<int> path;
    vector<bool> st;
    vector<vector<int>> permuteUnique(vector<int>& nums) &#123;
        sort(nums.begin(), nums.end());

        n = nums.size();
        path = vector<int> (n);
        st = vector<bool> (n);

        dfs(nums, 0);
        return ans;
    &#125;

    void dfs(vector<int> &nums, int u)
    &#123;
        if ( u == n )
        &#123;
            ans.push_back(path);
            return ;
        &#125;

        for (int i = 0; i < n; i ++)
        &#123;
            if (!st[i])
            &#123;
                if (i && nums[i - 1] == nums[i] && !st[i - 1]) continue;
                st[i] = true;
                path[u] = nums[i];
                dfs(nums, u + 1);
                st[i] = false;
            &#125;
        &#125;
    &#125;
&#125;;

LeetCode 48. 旋转图像

题目类型

  1. 技巧型

题目链接

https://leetcode.cn/problems/rotate-image/

思路

看看LeetCode题解就好,先斜翻转,再竖翻转

AC代码

class Solution &#123;
public:
    static void swap(vector<vector<int>>& matrix, int x1, int y1, int x2, int y2)
    &#123;
        int t = matrix[x1][y1];
        matrix[x1][y1] = matrix[x2][y2];
        matrix[x2][y2] = t;
    &#125;

    void rotate(vector<vector<int>>& matrix) &#123;
        int n = matrix.size();
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < i; j ++)
                swap(matrix, i, j, j, i);
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n / 2; j ++)
                swap(matrix, i, j, i, n - j - 1);
    &#125;
&#125;;

LeetCode 49. 字母异位词分组

题目类型

  1. 哈希表

题目链接

https://leetcode.cn/problems/group-anagrams/

思路

使用哈希表映射即可,每个组的异位词对字符排好序之后相等,例如abc、bac、cba排好序之后是abc,将其映射放入同一个组即可
例如hash[‘abc’] = [‘abc’, ‘bac’, ‘cba’]

AC代码

class Solution &#123;
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) &#123;
        unordered_map<string, vector<string>> hash;

        for (string& str : strs)
        &#123;
            string t = str;
            sort(str.begin(), str.end());
            hash[str].push_back(t);
        &#125;

        vector<vector<string>> res;
        for (auto& item : hash)
        &#123;
            res.push_back(item.second);
        &#125;
        return res;
    &#125;
&#125;;

LeetCode 50. Pow(x, n)

题目类型

  1. 快速幂

题目链接

https://leetcode.cn/problems/powx-n/

思路

参考大佬题解
https://leetcode.cn/problems/powx-n/solution/50-powx-n-kuai-su-mi-qing-xi-tu-jie-by-jyd/

AC代码

class Solution &#123;
public:
    double myPow(double x, int n) &#123;
        typedef long long LL;
        LL k = abs(LL(n));// 注意 n 为 INT_MIN时,abs 会爆掉 int。
        bool is_minus = n < 0;
        double res = 1;
        for (; k; k >>= 1)
        &#123;
            if (k & 1) res *= x;
             x *= x;
        &#125;
        if (is_minus) return 1/res;
        return res;
    &#125;
&#125;;

  转载请注明: Justin博客 LeetCode刷题记41-50

 上一篇
408相关算法刷题【树篇】 408相关算法刷题【树篇】
LeetCode 94. 二叉树的中序遍历题目类型 中序遍历 题目链接 https://leetcode.cn/problems/binary-tree-inorder-traversal 思路AC代码class Solution &a
下一篇 
408相关算法刷题【图论】 408相关算法刷题【图论】
LeetCode 133. 克隆图题目类型 深拷贝 dfs 题目链接 https://leetcode.cn/problems/clone-graph/ 思路 由于是无向边,使用哈希表(原图,克隆图)避免dfs的时候产生回路,死循环 写
  目录