leetcode刷题详解十

188. 买卖股票的最佳时机 IV(最多买卖k次)
  • 注意事项

    这道题和最多买卖两次是一模一样的思路就是把2换成k了但是还是有几个地方需要注意的

    1. 给的整数数组可能为0
    2. k其实没有很大,可以想一下,最多为n/2(n是数组的长度)
int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        if(n == 0){
            return 0;
        }
        k = min(k, n/2);
        vector<vector<vector<int>>> dp(n+1,vector<vector<int>>(k+1, vector<int>(2, 0)));
        //dp[1][k][0] = 0 && dp[1][k][1] = -prices[0]
        for(int i = 0; i < k + 1; i++){
            dp[1][i][0] = 0;
            dp[1][i][1] = -prices[0];
        }
        for(int i = 2; i < n + 1; i++){
            for(int j = 1; j < k + 1; j++){
                dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1] + prices[i-1]);
                dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j-1][0] - prices[i-1]);
            }
        }
        return dp[n][k][0];
    }
309. 最佳买卖股票时机含冷冻期(买卖多次)
  • 注意事项

    含冷冻期,说明一个事儿:即如果你买了的话,你必须是i-2买的,不能是i-1了!!!

int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if(n == 0){
            return 0;
        }
        //尽可能多的完成交易,也就说不限制次数
        vector<vector<int>> dp(n+1, vector<int>(2, 0));
        dp[1][0] = 0;
        dp[1][1] = -prices[0];
        for(int i = 2; i < n + 1; i++){
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i-1]);
            dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i-1]);
        }
        return dp[n][0];
    }
714. 买卖股票的最佳时机含手续费(买卖多次)
  • 注意事项

    有手续费而已,无非就是卖出的时候减去手续费,简单!

int maxProfit(vector<int>& prices, int fee) {
        int n = prices.size();
        if(n == 0){
            return 0;
        }
        vector<vector<int>> dp(n + 1, vector<int>(2, 0));
        dp[1][0] = 0;
        dp[1][1] = -prices[0];
        for(int i = 2; i < n + 1; i++){
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i-1]- fee);
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i-1]);
        }
        return dp[n][0];
    }

子序列问题

子序列问题是常见的算法问题,而且并不好解决。

首先,子序列问题本身就相对子串、子数组更困难一些,因为前者是不连续的序列,而后两者是连续的,就算穷举你都不一定会,更别说求解相关的算法问题了。

而且,子序列问题很可能涉及到两个字符串,比如前文「最长公共子序列」,如果没有一定的处理经验,真的不容易想出来。所以本文就来扒一扒子序列问题的套路,其实就有两种模板,相关问题只要往这两种思路上想,十拿九稳。

一般来说,这类问题都是让你求一个最长子序列,因为最短子序列就是一个字符嘛,没啥可问的。一旦涉及到子序列和最值,那几乎可以肯定,考察的是动态规划技巧,时间复杂度一般都是 O(n^2)

原因很简单,你想想一个字符串,它的子序列有多少种可能?起码是指数级的吧,这种情况下,不用动态规划技巧,还想怎么着?

既然要用动态规划,那就要定义 dp 数组,找状态转移关系。我们说的两种思路模板,就是 dp 数组的定义思路。不同的问题可能需要不同的 dp 数组定义来解决。

674. 最长连续递增序列
  • 注意事项

    贪心足以,不用动态规划了!

int findLengthOfLCIS(vector<int>& nums) {
        int n = nums.size();
        int max_len = 1;
        int count = 1;
        for(int i = 1; i < n ; i++){
            if(nums[i] > nums[i-1]){
                count++;
                max_len = max(max_len, count);
            }else{
                count = 1;
            }
        }
        return max_len;
    }
718. 最长重复子数组
  • 这道题动态规划不太好想,如果画个图会好一点,因此我就随便在网上找一张图了。

    7EFA9A32B19DA856AB78C8D29AD55875.png

    这张图对于理解二维dp数组很有帮助

    这里面 d p [ i ] [ j ] dp[i][j] dp[i][j]表示对于第一个数组前i个,和第二个数组前j个元素相等的数量,然后用一个max_com来存储个最大值,其实这种dp不太好想,还是画个dp来理解一下比较好

int findLength(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size();
        int n2 = nums2.size();
        int max_com = 0;
        vector<vector<int>> dp(n1+1, vector<int>(n2+1, 0));
        for(int i = 1; i < n1 + 1; i++){
            for(int j = 1; j < n2 + 1; j++){
                if(nums1[i-1] == nums2[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                    max_com = max(max_com, dp[i][j]);
                }
            }   
        }
        return max_com;
    }
  • 滑动窗口

    参考链接

int findLength(vector<int>& nums1, vector<int>& nums2) {
    int n1 = nums1.size();
    int n2 = nums2.size();
    return n1 > n2 ? sliding(nums2, nums1) : sliding(nums1, nums2);
}
int sliding(vector<int>& short_vec, vector<int>& long_vec){
    int n1 = short_vec.size();
    int n2 = long_vec.size();
    int max_repeat = 0;

    //短的和长的数组的最右边对齐
    for(int i = 1; i <= n1; i++){
        int tmp = get_repeat(short_vec, 0, long_vec, n2-i,i);
        cout<<"tmp1:"<<tmp<<endl;
        max_repeat = max(tmp, max_repeat);
    }

    //短的和长的数组的最左边对齐
    //以长数组的长度为参考
    for(int i = n2; i - n1>=0; i-- ){
        int tmp = get_repeat(short_vec, 0, long_vec, i-n1, n1);
        cout<<"tmp2:"<<tmp<<endl;
        max_repeat = max(tmp, max_repeat);
    }

    //短数组的右边和长数组的左边对齐
    //以短数组的长度为参考
    for(int i = n1; i >= 1; i--){
        int tmp = get_repeat(short_vec, n1-i, long_vec, 0, i);
        cout<<"tmp3:"<<tmp<<endl;
        max_repeat = max(tmp, max_repeat);
    }
    return max_repeat;
}

int get_repeat(vector<int>& short_vec, int i, vector<int>& long_vec, int j, int common_len){
    int max_repeat = 0;
    int count = 0;    
    for(int index = 0; index < common_len; index++){
        if(short_vec[i+index] == long_vec[j+index]){
            count++;
            max_repeat = max(count, max_repeat);
        }else{
            max_repeat = max(count, max_repeat);
            count = 0;
        }
    }
    return max_repeat;
} 
53. 最大子序和
  • 注意事项,这道题简单是简单,状态转移方程也不难。但是要记住这道题不是求得dp[n]!而是求dp数组的最大值
int maxSubArray(vector<int>& nums) {
        //这道题一眼dp不解释
        int n = nums.size();
        vector<int> dp(n + 1, INT_MIN);
        dp[1] = nums[0];
        for(int i = 2; i < n + 1; i++){
            dp[i] = max(dp[i-1]+nums[i-1], nums[i-1]);
        }
        int max_sum = INT_MIN;
        for(auto n : dp){
            max_sum = max(max_sum, n);
        }
        return max_sum;
    }
⭕️300. 最长递增子序列

这道题第二次做的时候一时间没有想到还。之前我老是想着nums[i-1]与nums[i-2]做匹配,其实是不对的,因为相邻的两个数其实没什么关系,不能这样子比较

int lengthOfLIS(vector<int>& nums) {
    int n = nums.size();
    vector<int> dp(n + 1, 1);
    for(int i = 2; i < n + 1; i++){
        for(int j = 1; j < i; j++){
            if(nums[i - 1] > nums[j - 1]){
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }
    int max_sub = 0;
    for(auto n:dp){
        max_sub = max(max_sub, n);
    }
    return max_sub;
}

int lengthOfLIS(vector<int>& nums) {
    int n = nums.size();
    vector<int> dp(n+1, 1);
    int tmp = nums[0];
    for(int i = 2; i < n + 1; i++){
        int tmp = 1;
        for(int j = 1; j < i; j++){
            if(nums[i-1] > nums[j-1]){
                tmp = max(tmp, dp[j] + 1);
            }
        }
        dp[i] = tmp;
    }
    sort(dp.begin(), dp.end(), std::greater<int>());
    return dp[0];
}

二分

时间复杂度nlogn

维护一个结果数组,如果当前元素比结果数组的值都大的的话,就追加在结果数组后面(相当于递增序列长度加了1);否则的话用当前元素覆盖掉第一个比它大的元素(增长缓慢才可能是最长的)(这样做的话后续递增序列才有可能更长,即使并没有更长,这个覆盖操作也并没有副作用哈,当然这个覆盖操作可能会让最终的结果数组值并不是最终的递增序列值,这无所谓)

操作只有两个:覆盖和追加,只有大于最后一个元素才会追加,其他时候都是覆盖

//比较粗糙的二分,每次循环都求了res数组的大小,效率太低
 int lengthOfLIS(vector<int>& nums) {
     int n = nums.size();
     vector<int> res;
     res.push_back(nums[0]);
     int tmp = nums[0];
     for(int i = 1; i < n; i++){
         if(nums[i] > tmp){
             res.push_back(nums[i]);
             tmp = nums[i];
         }
         else if(tmp == nums[i]){
             continue;
         }
         else{
             int index = lower_bound(res.begin(), res.end(), nums[i]) - res.begin();
             cout<<"nums[i]:"<<nums[i]<<endl;
             cout<<"index:"<<index<<endl;
             res[index] = nums[i];
             int n = res.size();
             tmp = res[n-1];
         }
     }
     return res.size();
 }

//改进的二分
nt lengthOfLIS(vector<int>& nums) {
    int n = nums.size();
    vector<int> res;
    res.push_back(nums[0]);
    int count = 0;
    for(int i = 1; i < n; i++){
        int index = lower_bound(res.begin(), res.end(), nums[i]) - res.begin();
        //之前用的是upper_bound,结果[4,10,4,3,8,9]未通过
        if(index > count){
            res.push_back(nums[i]);
            count++;
        }else{
            res[index] = nums[i];
        }

    }
    return res.size();
}
⭕️1143. 最长公共子序列
  • 最长公共子序列问题是一类问题,包括下面的583和712题,都是一样的

    公共子序列,打表就能做出来了!!典型的打表题

  • 以下是代码部分

    int longestCommonSubsequence(string text1, string text2) {
        int n = text1.size();
        int m = text2.size();
        vector<vector<int>> dp(n+1, vector<int>(m+1, 0));
        for(int i = 1; i < n + 1; i++){
            for(int j = 1; j < m + 1; j++){
                if(text1[i - 1] == text2[j - 1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else{
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        return dp[n][m];
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/196557.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大型网站系统架构演化(Web)

大型网站系统架构演化 大型网站系统架构演化需要关注的维度涉及的技术演进过程单体架构垂直架构使用缓存改善网站性能缓存与数据库的数据一致性问题缓存技术对比Redis分布式存储方案Redis集群切片的常见方式Redis数据类型Redis 淘汰算法 大型网站系统架构演化 需要关注的维度 …

2024年最受欢迎的项目管理工具盘点

十大项目管理系统包括&#xff1a;1.产品研发项目管理工具&#xff1a;PingCode&#xff1b;2.通用项目协作工具&#xff1a;Worktile&#xff1b;3.开源项目管理系统&#xff1a;Redmine&#xff1b;4.IT/敏捷项目管理系统&#xff1a;Jira&#xff1b;5.免费个人项目管理&…

NX二次开发UF_CURVE_create_arc_point_point_radius 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_create_arc_point_point_radius Defined in: uf_curve.h int UF_CURVE_create_arc_point_point_radius(tag_t point1, tag_t point2, double radius, UF_CURVE_limit_p_t l…

问答社区运营的核心是什么?

问答社区是用户在平台上获得信息的一种方式&#xff0c;一般问答社区适用于医疗行业&#xff0c;法律行业等专业领域的行业&#xff0c;可以划分为知识型分享社区的一种&#xff0c;用户提供提问&#xff0c;邀请回答&#xff0c;选择最佳回复&#xff0c;设置问题围观&#xf…

字符串逆序问题

写一个函数&#xff0c;可以将任意输入的字符串逆序&#xff08;要可以满足多组输入&#xff09; 这个题有三个点 1.要读入键盘输入的字符串&#xff0c;所以要用到字符串输入函数 2.可以进行多组输入 3.把输入的n组字符串都逆序 #define _CRT_SECURE_NO_WARNINGS 1 #incl…

Portraiture2024最新Photoshop磨皮插件更新啦

Portraiture是一款由Imagenomic公司研发的Photoshop磨皮插件。该插件以其优秀的磨皮效果&#xff0c;成为了众多摄影师和化妆师使用的首选插件。Portraiture主要用于影楼、婚纱、时尚摄影等各个领域。其主要特点是能够轻松地模拟人眼的视觉感受&#xff0c;自然地修饰人像照片。…

【Linux专题】http(s)代理

【赠送】IT技术视频教程&#xff0c;白拿不谢&#xff01;思科、华为、红帽、数据库、云计算等等_厦门微思网络的博客-CSDN博客文章浏览阅读444次。风和日丽&#xff0c;小微给你送福利~如果你是小微的老粉&#xff0c;这里有一份粉丝福利待领取...如果你是新粉关注到了小微&am…

元宇宙的八个关键技术介绍!

人工智能&#xff08;AI&#xff09;、物联网、增强现实、虚拟现实、区块链、NFT、3D建模、空间和边缘计算等技术使最元宇宙开发成为可能。本文对元宇宙的8个关键技术进行了介绍。 人工智能 人工智能技术中的目标分割、目标追踪、姿态估计等是元宇宙场景中感知现实的关键工具&…

【笔记】小白学习电路维修

学习视频&#xff08;b站&#xff09;&#xff1a;从0开始学电路 从0开始学电路维修 p1 黄色长方体元件P2 故障率最高的元件p3带芯铜丝线圈是什么区分电感和变压器接入电路分析&#xff1a; p4 交流和直流分界线整流桥接线整流桥故障判断 带色环的不一定是电阻 p1 黄色长方体元…

51单片机项目(16)——基于51单片机的水箱冷却系统

1.项目背景 汽车水箱又称散热器&#xff0c;是汽车冷却系统中主要机件&#xff1b;其功用是散发热量&#xff0c;冷却水在水套中吸收热量&#xff0c;流到散热器后将热量散去&#xff0c;再回到水套内而循环不断。从而达到散热调温的效果。它还是汽车发动机的重要组成部分。 汽…

解决ssh使用public key远程登录服务器拒绝问题

目录 使用场景windows安装ssh客户端使用powershell ssh登录服务器生成密钥文件ubuntu ssh服务器配置使用vscode远程登录使用Xshell远程登录使用MobaXtem远程登录Server refused our key问题解决方案 使用场景 使用vscode远程ssh登录使用public key不需要输入密码,比较方便. w…

Java 之 lambda 表达式(一)

目录 一. 前言 二. lambda 表达式语法 2.1. 语法1&#xff1a;无参&#xff0c;无返回值 2.2. 语法2&#xff1a;一个参数&#xff0c;无返回值 2.3. 语法3&#xff1a;两个参数&#xff0c;lambda 体中有多条语句 2.4. 语法4&#xff1a;两个以上参数&#xff0c;有返回…

Java 常用容器

目录 列表栈&#xff08;类&#xff09;队列(接口)setMap 列表 package com.czl;import java.util.ArrayList; import java.util.List; //AltEnter导入包 public class Main {public static void main(String[] args) throws Exception{List<Integer> list new ArrayLis…

群晖NAS配置之自有服务器ngrok实现内网穿透

群晖NAS配置之自有服务器ngrok实现内网穿透 前言-内网穿透 内网穿透是指通过一种技术让外部网络可以访问到内网的NAS设备&#xff0c;这样即使在不同网络环境下&#xff0c;也能够远程访问和管理NAS设备。以下是一些常见的内网穿透方案&#xff1a; Synology官方提供的Quick…

【Java Spring】SpringBoot常用插件

文章目录 1、Lombok1.1 IDEA社区版安装Lombok1.2 IDEA专业版安装Lombok1.3 Lombok的基本使用 2、EditStarters2.1 IDEA安装EditStarters2.2 EditStarters基本使用方法 1、Lombok 是简化Java开发的一个必要工具&#xff0c;lombok的原理是编译过程中将lombok的注解给去掉并翻译…

二百零八、Hive——HiveSQL异常:Select查询数据正常,但SQL语句加上group by查询数据为空

一、目的 在HiveSQL的DWD层中&#xff0c;需要对原始数据进行去重在内的清洗&#xff0c;结果一开始其他数据类型的清洗工作都正常&#xff0c;直到碰到转向比数据。 一般的SQL查询有数据&#xff0c;但是加上group by以后就没数据&#xff1b; 一般的SQL查询有数据&#xf…

很清楚展示GPT插件的调用过程,人工智能(AI)的潜在危险与好处 超级智能 未来

好处&#xff0c;未来 很清楚展示GPT插件的调用过程&#xff1a; 把请求和要求发chatGPT chatGPT返回markdown格式发给插件 插件返回结果给用户。 你不用别人用。 人工智能&#xff08;AI&#xff09;的最危险之处通常与以下几个方面有关&#xff1a; 自主决策能力过强&…

轻量级项目群管理

敏捷开发流程管理&#xff1a; Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 Leangoo支持敏捷研发管理全流程&#xff0c;包括小型团队敏捷开发&#xff0c;…

创建SpringBoot Helloword 程序详细步骤

本文档实现SpringBoot hello word 程序&#xff0c;翻译于Spring | Quickstart 目录 一、项目创建步骤1.1 创建项目1.2 添加代码1.3 运行 参考教程 一、项目创建步骤 1.1 创建项目 在官网Spring Initializr上创建项目 1.2 添加代码 在IDE中打开项目并在src/main/java/com/zo…

springboot集成springsecurity

转载自&#xff1a;www.javaman.cn 1、整合springsecurity 添加pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency>2、springsecurity认证授权流程…