IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode 41~50 -> 正文阅读

[数据结构与算法]leetcode 41~50

lc 41 ~ 50

41. 缺失的第一个正数

原地哈希

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        //原地哈希,映射 nums[i] = i + 1
        int n = nums.size();
        for(int i = 0; i < n; i++)
            while(nums[i] > 0 && nums[i] <= n && nums[i] != nums[nums[i] - 1]){
                int temp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = temp;
            }
        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) {
        stack<int> stk;//单调递减栈,放索引
        int res = 0, len = height.size();
        for(int i = 0; i < len; i++){
            int last = 0;
            while(stk.size() && height[stk.top()] <= height[i]){
                res += (height[stk.top()] - last) * (i - stk.top() - 1);
                last = height[stk.top()];
                stk.pop();
            }
            if(stk.size()) res += (i - stk.top() - 1) * (height[i] - last);
            stk.push(i);
        }
        return res;
    }
};

43. 字符串相乘

高精度乘法

class Solution {
public:
    string multiply(string num1, string num2) {
        if(num1 == "0" || num2 == "0") return "0";
        int len1 = num1.length(), len2 = num2.length();
        vector<int> a, b;
        vector<int> c(len1 + len2);
        string ans;
        for(int i = num1.length() - 1; i >= 0; i--) a.push_back(num1[i] - '0');
        for(int i = num2.length() - 1; i >= 0; i--) b.push_back(num2[i] - '0');
        for(int i = 0; i < num1.length(); i++)
            for(int j = 0; j < num2.length(); j++)
                c[i + j] += a[i] * b[j];
        //开始搞进位
        int t = 0;//乘积最多len1 + len2 - 1位,所以最后不用管t到最后会不会是非零,一定是0
        for(int i = 0; i < len1 + len2; i++){
            t += c[i];
            c[i] = t % 10;
            t /= 10;
        }
        //开始去零
        int k = c.size() - 1;
        //为什么不是>=0,因为如果结果是0的话就要保留一位0
        while(k > 0 && !c[k]) k--;
        for(int j = k; j >= 0; j--) ans += c[j] + '0';
        return ans;
    }
};

44. 通配符匹配

DP,自己写的,虽然找了很久bug

class Solution {
public:
    bool isMatch(string s, string p) {
        s = ' ' + s, p = ' ' + p;
        int n = s.size(), m = p.size();
        vector<vector<bool>> dp(n, vector<bool>(m));
        //dp[i][j]:s前i与p前j匹配是否成功
        dp[0][0] = true;//都空时当然true
        //s不空p空必false;s空p不空,只要都是*就true
        int k = 1;
        while(k < m && p[k] == '*') dp[0][k++] = true;
        for(int i = 1; i < n; i++)
            for(int j = 1; j < m; j++){
                //p[j]三种情况,字母,?, *
                if(p[j] != '?' && p[j] != '*')
                    dp[i][j] = dp[i - 1][j - 1] && (p[j] == s[i]);
                else if(p[j] == '?'){
                    dp[i][j] = dp[i - 1][j - 1];
                }
                else{
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                }
            }
        return dp[n - 1][m - 1];
    }
};

y总版,码风很值得学习

class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.size(), m = p.size();
        s = ' ' + s, p = ' ' + p;
        vector<vector<bool>> dp(n + 1, vector<bool>(m + 1));
        dp[0][0] = true;
        for(int i = 0; i <= n; i++)
            for(int j = 1; j <= m; j++){
                if(p[j] == '*')
                    dp[i][j] = dp[i][j - 1] || i && dp[i - 1][j];//运算优先级先与再或
                else
                    dp[i][j] = (p[j] == s[i] || p[j] == '?') && i && dp[i - 1][j - 1];
            }
        return dp[n][m];
    }
};

45. 跳跃游戏 II

贪心,正向查找可到达的最大位置

class Solution {
public:
    int jump(vector<int>& nums) {
        int end = 0, maxPos = 0, step = 0, len = nums.size();
        for(int i = 0; i < len - 1; i++){
            maxPos = max(maxPos, i + nums[i]);//更新所能到达的最远距离
            //如果到达边界就更新边界,步数加1
            if(i == end){
                end = maxPos;
                step++;
            }
        }
        return step;
    }
};

DP

class Solution {
public:
    int jump(vector<int>& nums) {
        int len = nums.size();
        vector<int> dp(len);//dp[i]表示从0到i的最小步数,dp[0]=0
        //[2,3,1,1,4]:则可以发现dp : 0 1 1 2 2可以发现dp是分段递增的
        //则可以把j表示为需要走1步可以到i的位置,即为上一层,则状态转移dp[i]=d[j]+1
        for(int i = 1, j = 0; i < len; i++){
            //寻找一个可以到达i位置的j
            while(j + nums[j] < i) j++; //题中满足一定可以到终点,j一定不会越界
            dp[i] = dp[j] + 1;
        }
        return dp[len - 1];
    }
};

46. 全排列

简单DFS

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;//因为path长度是确定的,所以建议像y总那样初始化先定好空间
    bool st[10];//存放每个是否选过了
    vector<vector<int>> permute(vector<int>& nums) {
        //path = vector<int>(nums.size());//这样path就不用反复push,pop了,直接修改就行
        dfs(nums, 0);
        return ans;
    }

    void dfs(vector<int>& nums, int u){
        if(u == nums.size()){
            ans.push_back(path);
        }
        for(int i = 0; i < nums.size(); i++){
            if(!st[i]){
                st[i] = true;
                //path[u] = nums[i];
                path.push_back(nums[i]);
                dfs(nums, u + 1);
                st[i] = false;
                path.pop_back();
            }
        }
    }
};

47. 全排列 II

DFS + set去重(效率低)

class Solution {
public:
    vector<vector<int>> ans;
    set<vector<int>> s;//去重
    bool st[10];

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<int> path(nums.size());
        dfs(nums, 0, path);
        return ans;
    }

    void dfs(vector<int>& nums, int u, vector<int>& path){
        if(u == nums.size()){
            if(s.find(path) == s.end()){
                ans.push_back(path);
                s.insert(path);
            }
            return;
        }
        for(int i = 0; i < nums.size(); i++){
            if(!st[i]){
                st[i] = true;
                path[u] = nums[i];
                // path.push_back(nums[i]);
                dfs(nums, u + 1, path);
                st[i] = false;
                // path.pop_back();
            }
        }
    }
};

巧妙的去重方法,排序

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<bool> st;

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        //先排序,将相等的数放一起
        sort(nums.begin(), nums.end());
        path = vector<int>(nums.size());
        st = vector<bool>(nums.size());
        dfs(nums, 0);
        return ans;
    }

    void dfs(vector<int>& nums, int u){
        if(u == nums.size()){
            ans.push_back(path);
            return;
        }
        for(int i = 0; i < nums.size(); i++){
            if(!st[i]){
                //去重,将相等的元素按优先级分好,前面的没用,这个就不能用,这样就不紊乱
                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;
            }
        }
    }
};

48. 旋转图像

脑筋急转弯

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        //方法:先沿副对角线翻转,再沿中轴翻转
        //证明正确性,方阵是一圈一圈的正方形组成,不妨验证正方形的正确性就行了
        //以一条边为参考,比如下边,沿对角线反转后,变为右边,而顺时针90度在左边,所以再沿中轴翻转即可
        //想一下,边上数的顺序也是对的,所以这个方法是对的
        for(int i = 0; i < n; i++)
            for(int j = 0; j < i; j++)
                swap(matrix[i][j], matrix[j][i]);
        for(int i = 0; i < n; i++)
            for(int l = 0, r = n - 1; l < r; l++, r--)
                swap(matrix[i][l], matrix[i][r]);
    }
};

49. 字母异位词分组

哈希表

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> hash;
        vector<vector<string>> ans;
        for(auto& s : strs){
            string temp = s;
            sort(temp.begin(), temp.end());//排完序后满足条件的就一样了
            hash[temp].push_back(s);
        }
        for(auto& item : hash) ans.push_back(item.second);
        return ans;
    }
};

50. Pow(x, n)

快速幂

class Solution {
public:
    double myPow(double x, int n) {
        typedef long long LL;
        bool is_minus = false;
        double ans = 1;
        if(n < 0) is_minus = true;
        //为什么用LL,-2147483648取绝对值会溢出int
        for(LL k = abs((LL)n); k; k >>= 1){
            if(k & 1) ans *= x;
            x *= x;
        }
        if(is_minus) ans = 1 / ans;
        return ans;
    }
};

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:40:34  更:2022-04-24 09:40:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:34:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码