《LeetCode 顺序刷题》41 - 50

41、[困难] 缺失的第一个正数

数组 哈希表

哈希表

复制代码
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int& num : nums) {
            if (num <= 0) {
                num = n + 1;
            }
        }
        for (int i = 0; i < n; i++) {
            int num = abs(nums[i]);
            if (num <= n) {
                nums[num - 1] = -abs(nums[num - 1]);
            }
        }
        for (int i = 0; i < n; i++) {
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        return n + 1;
    }
};

置换

复制代码
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
                swap(nums[nums[i] - 1], nums[i]);
            }
        }
        for (int i = 0; i < n; i++) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return n + 1;
    }
};

42、[困难] 接雨水

数组 双指针 动态规划

动态规划

复制代码
class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        if (n == 0)
            return 0;

        vector<int> leftMax(n);
        leftMax[0] = height[0];
        for (int i = 1; i < n; i++) {
            leftMax[i] = max(leftMax[i - 1], height[i]);
        }

        vector<int> rightMax(n);
        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            rightMax[i] = max(rightMax[i + 1], height[i]);
        }

        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans += min(leftMax[i], rightMax[i]) - height[i];
        }

        return ans;
    }
};

单调栈

复制代码
class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        stack<int> stk;
        int n = height.size();
        for (int i = 0; i < n; i++) {
            while (!stk.empty() && height[i] > height[stk.top()]) {
                int top = stk.top();
                stk.pop();
                if (stk.empty()) break;

                int left = stk.top();
                int curWidth = i - left - 1;
                int curHeight = min(height[left], height[i]) - height[top];
                ans += curWidth * curHeight;
            }
            stk.push(i);
        }
        return ans;
    }
};

双指针

复制代码
class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        int left = 0, right = height.size() - 1;
        int leftMax = 0, rightMax = 0;
        while (left < right) {
            leftMax = max(leftMax, height[left]);
            rightMax = max(rightMax, height[right]);
            if (height[left] < height[right]) {
                ans += leftMax - height[left];
                ++left;
            } else {
                ans += rightMax - height[right];
                --right;
            }
        }
        return ans;
    }
};

43、[中等] 字符串相乘

数学 字符串

复制代码
class Solution {
public:
    string multiply(string num1, string num2) {
        // 解法:无进位相乘后相加,然后处理进位
        int m = num1.size(), n = num2.size();
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());
        vector<int> tmp(m + n - 1);

        // 1. 无进位相乘后相加
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                tmp[i + j] += (num1[i] - '0') * (num2[j] - '0');
            }
        }

        // 2. 处理进位
        int cur = 0, t = 0;
        string ret;
        while (cur < m + n - 1 || t) {
            if (cur < m + n - 1) {
                t += tmp[cur++];
            }
            ret += t % 10 + '0';
            t /= 10;
        }

        // 3. 处理前导零
        while (ret.size() > 1 && ret.back() == '0') {
            ret.pop_back();
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

44、[困难] 通配符匹配

字符串 动态规划

复制代码
class Solution {
public:
    bool isMatch(string s, string p) {
        s = " " + s;
        p = " " + p;
        int m = s.size();
        int n = p.size();
        vector<vector<bool>> dp(m, vector(n, false));
        dp[0][0] = true;
        for (int j = 1; j < n; j++) {
            if (p[j] == '*') {
                dp[0][j] = true;
            } else {
                break;
            }
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (p[j] == '*') {
                    dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
                } else {
                    dp[i][j] =
                        (p[j] == '?' || s[i] == p[j]) && dp[i - 1][j - 1];
                }
            }
        }
        return dp[m - 1][n - 1];
    }
};

45、[中等] 跳跃游戏 Ⅱ

贪心

复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        int ret = 0;
        int start = 0;
        int end = 1;
        while (end < nums.size()) {
            int maxPos = 0;
            for (int i = start; i < end; i++) {
                // 能跳到最远的距离
                maxPos = max(maxPos, i + nums[i]);
            }
            start = end;
            end = maxPos + 1;
            ret++;
        }
        return ret;
    }
};

class Solution {
public:
    int jump(vector<int>& nums) {
        int ret = 0;
        int end = 0;
        int maxPos = 0;
        for (int i = 0; i < nums.size() - 1; i++) {
            // 能跳到最远的距离
            maxPos = max(maxPos, i + nums[i]);

            if (i == end) {
                end = maxPos;
                ret++;
            }
        }
        return ret;
    }
};

46、[中等] 全排列

数组 回溯

复制代码
class Solution {
private:
    vector<vector<int>> ret;
    vector<int> path;
    bool check[7];

    void dfs(vector<int>& nums) {
        if (nums.size() == path.size()) {
            ret.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
            if (check[i] == false) {
                path.push_back(nums[i]);
                check[i] = true;
                dfs(nums);

                // 回溯 -> 恢复现场
                path.pop_back();
                check[i] = false;
            }
        }
    }

public:
    vector<vector<int>> permute(vector<int>& nums) {
        dfs(nums);
        return ret;
    }
};

47、[中等] 全排列 Ⅱ

数组 回溯

复制代码
class Solution {
private:
    vector<int> path;
    vector<vector<int>> ret;
    bool check[9];

    void dfs(vector<int>& nums, int pos) {
        if (pos == nums.size()) {
            ret.push_back(path);
            return;
        }

        for (int i = 0; i < nums.size(); ++i) {
            // 剪枝
            if (check[i] == true ||
                (i != 0 && nums[i] == nums[i - 1] && check[i - 1] == false)) {
                continue;
            }

            path.push_back(nums[i]);
            check[i] = true;
            dfs(nums, pos + 1);
            path.pop_back();
            check[i] = false;
        }
    }

public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        dfs(nums, 0);
        return ret;
    }
};

48、[中等] 旋转图像

数组 数学

复制代码
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < (n + 1) / 2; ++j) {
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[n - j - 1][i];
                matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
                matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
                matrix[j][n - i - 1] = tmp;
            }
        }
    }
};

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();

        // 水平翻转
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < n; ++j) {
                swap(matrix[i][j], matrix[n - i - 1][j]);
            }
        }

        // 主对角线翻转
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                swap(matrix[i][j], matrix[j][i]);
            }
        }
    }
};

49、[中等] 字母异位词分组

排序 哈希表 字符串

复制代码
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> hash;

        // 1. 把所有的字母异位词分组
        for (const auto& s : strs)
        {
            string tmp = s;
            sort(tmp.begin(), tmp.end());
            hash[tmp].push_back(s);
        }

        // 2. 结果提取出来
        vector<vector<string>> ret;
        for (const auto& [x, y] : hash)
        {
            ret.push_back(y);
        }
        return ret;
    }
};

50、[中等] Pow(x, n)

递归 数学

复制代码
class Solution {
public:
    double myPow(double x, int n) {
        if (n < 0) {
            return 1 / pow(x, -(long long)n);
        }

        return pow(x, n);
    }

    double pow(double x, long long n) {
        if (n == 0) {
            return 1.0;
        }

        double tmp = pow(x, n / 2);
        return n % 2 == 0 ? tmp * tmp : tmp * tmp * x;
    }
};
相关推荐
Nuopiane40 分钟前
MyPal3(3)
java·开发语言
Ama_tor40 分钟前
Flask零基础进阶(中)
后端·python·flask
重生之我是Java开发战士41 分钟前
【递归、搜索与回溯】二叉树中的深度优先搜索:布尔二叉树,求根节点到叶节点数字之和,二叉树剪枝,验证二叉搜索树,第K小的元素,二叉树的所有路径
算法·深度优先·剪枝
篮l球场41 分钟前
矩阵置零
算法
love530love41 分钟前
Windows 11 源码编译 vLLM 0.16 完全指南(RTX 3090 / CUDA 12.8 / PyTorch 2.7.1)
人工智能·pytorch·windows·python·深度学习·vllm·vs 2022
mjhcsp42 分钟前
C++剪枝解析
c++·剪枝
wregjru42 分钟前
【网络】5.HTTP 协议详解与实现
c++
lihihi43 分钟前
P1650 [ICPC 2004 Shanghai R] 田忌赛马(同洛谷2587)
开发语言·算法·r语言
进击的小头43 分钟前
第3篇:最优控制理论数学基础——矩阵与向量的导数
python·线性代数·机器学习·矩阵
朱一头zcy43 分钟前
[牛客]BC38 变种水仙花
算法