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];
    }
    

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win10 tensorrt源码编译onnx

直接利用官方源码&#xff0c;如下图&#xff0c;trtexec源码在TensorRT安装目录下&#xff0c;双击trtexec.sln文件&#xff0c;使用vs2019打开源码工程。 如下图&#xff0c;以yolov8为例子&#xff0c;编译成功项目之后&#xff0c;设置命令行参数&#xff1a; --onnxd:/yo…

IDEA不支持Java8了怎么办?

IDEA不支持Java8了怎么办&#xff1f; 01 异常发生场景 当我准备创建一个springboot项目时&#xff0c;发现Java8没了 02 问题的产生及其原因 查阅了官方文档之后&#xff0c;确认了是Spring Boot 不再支持 Java 8&#xff0c;不是我的问题&#xff0c;这一天终于还是来了 0…

pytest自动化测试执行环境切换的两种解决方案

一、痛点分析 在实际企业的项目中&#xff0c;自动化测试的代码往往需要在不同的环境中进行切换&#xff0c;比如多套测试环境、预上线环境、UAT环境、线上环境等等&#xff0c;并且在DevOps理念中&#xff0c;往往自动化都会与Jenkins进行CI/CD&#xff0c;不论是定时执行策略…

拆解按摩器:有意思的按键与LED控制电路,学习借鉴一下!

拆解 外观和配色个人感觉还行,比较青春 拉开拉链&#xff0c;拆开外面的布面&#xff0c;里面还有一层纱面 按键部分使用魔术贴固定 拆开纱面后&#xff0c;看到里面的结构&#xff0c;整体是一个海绵 可以看到如下&#xff0c;电池&#xff0c;按键板&#xff0c;充电线的三条…

鸿蒙(HarmonyOS)应用开发——应用程序入口UIAbility

概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互 UIAbility是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面 应用程序的几种交互界面形式 点击桌面图标进入应用 一个应用拉起另一个应用 最近任务列表切回应用 每一个UI Abili…

Rabbitmq发送邮件并消费邮件

&#x1f4d1;前言 本文主要是【Rabbitmq】——Rabbitmq发送邮件并消费邮件的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1…

java三大集合类--List

List Set Map 一、List 几个小问题&#xff1a; 1、接口可以被继承吗&#xff1f;&#xff08;可以&#xff09; 2、接口可以被多个类实现吗&#xff1f;&#xff08;可以&#xff09; 3、以下两种写法有什么区别&#xff1f; //List list1new List();是错误的因为List()…

js逆向-某赞滑块

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 前言 目标网站&#xff1a;aHR0cHM6Ly9hY2NvdW50LnlvdXphbi5j…

Hive数据库与表操作

文章目录 一、准备工作二、Hive数据库操作&#xff08;一&#xff09;Hive数据存储&#xff08;二&#xff09;创建数据库&#xff08;三&#xff09;查看数据库&#xff08;四&#xff09;修改数据库信息 一、准备工作 二、Hive数据库操作 &#xff08;一&#xff09;Hive数据…

uniapp地图基本使用及解决添加markers不生效问题?

uniapp地图使用 App端 通过 nvue 页面实现地图 文章目录 uniapp地图使用效果图templatejs添加 marker使用地图查看位置移到到当前位置 效果图 template <template><view class"mapWrap"><!-- #ifdef APP-NVUE --><map class"map-containe…

【Linux】Shell命令以及运行原理

目录 一、Linux是什么 二、Shell 三、为什么要有Shell 四、Shell的工作原理 一、Linux是什么 狭义上的Linux是指Linux内核本身&#xff0c;它是操作系统的核心部分&#xff0c;负责管理计算机的硬件资源&#xff08;如处理器、内存、设备等&#xff09;&#xff0c;提供基…

软著项目推荐 深度学习动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…