代码随想录算法训练营第36期 last day

最后一次更新,之后去复习专业课和简历

583两个字符串的删除操作

自己做出来了:

Code:

  1. class Solution {
  2. public:
  3. //找到公共子序列的最大长度dp 最小步数=串1.size-dp+串2.size-dp
  4.     int minDistance(string word1, string word2) {
  5.         vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1));
  6.         dp[0][0]=0;
  7.         for(int i=1;i<=word1.size();i++){
  8.             for(int j=1;j<=word2.size();j++){
  9.                 if(word1[i-1]==word2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
  10.                 else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
  11.             }
  12.         }
  13.         return word1.size()+word2.size()-2*dp[word1.size()][word2.size()];
  14.     }
  15. };

72编辑距离

没思路,明天学。积累经验

拓展思维:word2转变到word1也可以。

别人的删,就相当于我的增。Dp[i][j]=dp[i][j-1]+1

  1. class Solution {
  2. public:
  3.     int minDistance(string word1, string word2) {
  4.         vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1));
  5.         for(int i=0;i<=word1.size();i++) dp[i][0]=i;
  6.         for(int i=0;i<=word2.size();i++) dp[0][i]=i;
  7.         for(int i=1;i<=word1.size();i++){
  8.             for(int j=1;j<=word2.size();j++)
  9.             {
  10.                 if(word1[i-1]==word2[j-1]) dp[i][j]=dp[i-1][j-1];
  11.                 else dp[i][j]=min(dp[i-1][j]+1,min(dp[i][j-1]+1,dp[i-1][j-1]+1));
  12.             }
  13.         }
  14.         return dp[word1.size()][word2.size()];
  15.     }
  16. };

647回文子串

写的很好,我想不到用i j的距离(而不是索引字符)来做单字符与双字符的回文。

Code:

注意都是在s[i]==s[j]时候改值

  1. class Solution {
  2. public:
  3.     int countSubstrings(string s) {
  4.         int res = 0;
  5.         vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
  6.         for (int i = s.size() - 1; i >= 0; i--) {
  7.             for (int j = i; j < s.size(); j++) {
  8.                 if (s[j] == s[i]) {
  9.                     if (j - i <= 1) {
  10.                         res++;
  11.                         dp[i][j] = true;
  12.                     } else if (dp[i + 1][j - 1]) {
  13.                         res++;
  14.                         dp[i][j] = true;
  15.                     }
  16.                 }
  17.             }
  18.         }
  19.         return res;
  20.     }
  21. };

516最长回文子序列

经验题,继续学:

注意里面的加减符号别弄错,理解题意是关键。

  1. class Solution {
  2. public:
  3.     int longestPalindromeSubseq(string s) {
  4.         vector<vector<int>>dp(s.size(),vector<int>(s.size(),0));
  5.         for(int i=0;i<s.size();i++) dp[i][i]=1;
  6.         for(int i=s.size()-1;i>=0;i--){
  7.             for(int j=i+1;j<s.size();j++){
  8.                 if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2;
  9.                 else dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
  10.             }
  11.         }
  12.         return dp[0][s.size()-1];
  13.     }
  14. };

单调栈

整半天才发现自己把栈顶(top), 栈底给弄反了,要重做之前的题目。

739每日温度

朴素法,超时:

  1. class Solution {
  2. public:
  3. //朴素法
  4.     vector<intdailyTemperatures(vector<int>& temperatures) {
  5.         vector<intres(temperatures.size(),0);
  6.         for(int i=0;i<temperatures.size();i++){
  7.             int idx=temperatures[i];
  8.             for(int j=i+1;j<temperatures.size();j++){
  9.                 if(idx<temperatures[j]){
  10.                     res[i]=j-i;
  11.                     break;
  12.                 }
  13.             }
  14.         }
  15.         return res;
  16.     }
  17. };

注意!

单调栈里存的是下标。

未精简的代码:

  1. class Solution {
  2. public:
  3.     vector<intdailyTemperatures(vector<int>& temperatures) {
  4.         vector<intres(temperatures.size(),0);
  5.         stack<int> s;
  6.         s.push(0);
  7.         for(int i=1;i<temperatures.size();i++){
  8.             if(temperatures[i]<temperatures[s.top()]) s.push(i);
  9.             else if(temperatures[i]==temperatures[s.top()]) s.push(i);
  10.             else{
  11.                 while(!s.empty()&&temperatures[i]>temperatures[s.top()]){
  12.                     res[s.top()]=i-s.top();
  13.                     s.pop();
  14.                 }
  15.                 s.push(i);
  16.             }
  17.         }
  18.         return res;
  19.     }
  20. };

精简后的代码:

  1. class Solution {
  2. public:
  3.     vector<intdailyTemperatures(vector<int>& temperatures) {
  4.         vector<intres(temperatures.size(),0);
  5.         stack<int> s;
  6.         for(int i=0;i<temperatures.size();i++){
  7.             while(!s.empty()&&temperatures[i]>temperatures[s.top()]){
  8.                 res[s.top()]=i-s.top();
  9.                 s.pop();
  10.             }
  11.             s.push(i);
  12.         }
  13.         return res;
  14.     }
  15. };

496下一个更大元素i

没想到:“数组中没有重复数字,用map做两个数组的映射。

根据数值快速找到下标,还可判断nums2[i]是否在nums1中出现过。

当使用集合来解决哈希问题的时候,优先使用unordered_set,因为他的查询和增删效率是最优的。”

注意注释上的东西:

  1. class Solution {
  2. public:
  3.     vector<intnextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
  4.         unordered_map<int,intmap;
  5.         vector<intres(nums1.size(),-1);
  6.         for(int i=0;i<nums1.size();i++) map[nums1[i]]=i;
  7.         stack<int> s;
  8.         s.push(0);
  9.         for(int i=1;i<nums2.size();i++){
  10.             while(!s.empty()&&nums2[i]>nums2[s.top()]){
  11.                 if(map.count(nums2[s.top()])>0){
  12.                     //idx注意怎么求,别弄错
  13.                     int idx=map[nums2[s.top()]];
  14.                     res[idx]=nums2[i];
  15.                 }
  16.                 //这句话不要写在if里面
  17.                 s.pop();
  18.             }
  19.             s.push(i);
  20.         }
  21.         return res;
  22.     }
  23. };

待理清思路,二刷:

  1. class Solution {
  2. public:
  3.     vector<intnextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
  4.         unordered_map<int,intmap;
  5.         vector<intres(nums1.size(),-1);
  6.         for(int i=0;i<nums1.size();i++) map[nums1[i]]=i;
  7.         stack<int> s;
  8.         s.push(0);
  9.         for(int i=1;i<nums2.size();i++){
  10.             while(!s.empty()&&nums2[i]>nums2[s.top()]){
  11.                 if(map.count(nums2[s.top()])>0){
  12.                     res[map[nums2[s.top()]]]=nums2[i];
  13.                 }
  14.                 s.pop();
  15.             }
  16.             s.push(i);
  17.         }
  18.         return res;
  19.     }
  20. };

503下一个更大元素ii

1 很妙的想法:数组拼接,取res.size()/2

注意insert的写法:

  1. class Solution {
  2. public:
  3.     vector<intnextGreaterElements(vector<int>& nums) {
  4.         vector<intnewnums(nums.begin(),nums.end());
  5.         nums.insert(nums.end(),newnums.begin(),newnums.end());
  6.         vector<intres(nums.size(),-1);
  7.         stack<int> s;
  8.         s.push(0);
  9.         for(int i=1;i<nums.size();i++){
  10.             while(!s.empty()&&nums[i]>nums[s.top()]){
  11.                 res[s.top()]=nums[i];
  12.                 s.pop();
  13.             }
  14.             s.push(i);
  15.         }
  16.         res.resize(res.size()/2);
  17.         return res;
  18.     }
  19. };

2 对于“循环”,要想到:用mod (%)来操作。

要注意的是 ,res[idx];; idx=s.top()相关的。

  1. class Solution {
  2. public:
  3.     vector<intnextGreaterElements(vector<int>& nums) {
  4.         vector<intres(nums.size(),-1);
  5.         stack<int> s;
  6.         s.push(0);
  7.         for(int i=1;i<2*nums.size();i++){
  8.             while(!s.empty()&&nums[i%nums.size()]>nums[s.top()]){
  9.                 res[s.top()]=nums[i%nums.size()];
  10.                 s.pop();
  11.             }
  12.             s.push(i%nums.size());
  13.         }
  14.         return res;
  15.     }
  16. };

42接雨水,困难

对于不规则的阴影面积(由单位面积组成)求解,应当明确:按行计算还是按列计算。

按列计算,朴素法:一次性写对了,真的进步了很多,坚持每天复现+做复试真题来加强吧。

  1. class Solution {
  2. public:
  3.     int trap(vector<int>& height) {
  4.         int sum=0;
  5.         for(int i=0;i<height.size();i++){
  6.             if(i==0||i==height.size()-1continue;
  7.             int maxleft=height[0];
  8.             int maxright=height[height.size()-1];
  9.             for(int j=0;j<=i;j++) maxleft=max(maxleft,height[j]);
  10.             for(int j=height.size()-1;j>=i;j--) maxright=max(maxright,height[j]);
  11.             int mywater=min(maxleft,maxright)-height[i];
  12.             if(mywater>0) sum+=mywater;
  13.         }
  14.         return sum;
  15.     }
  16. };

按列计算,双指针优化:

双指针优化 求左右最大的语句写错了。在纸上写一下就写对了,不要空想:

求右边的最大:如果当前自己的高度是最大的,那么自己就是最大height[i],;

反正,我们需要继承之前的maxright结果。即:maxright[i+1];

  1. class Solution {
  2. public:
  3.     int trap(vector<int>& height) {
  4.         int sum=0;
  5.         vector<intmaxleft(height.size(),height[0]);
  6.         vector<intmaxright(height.size(),height[height.size()-1]);
  7.         for(int j=1;j<height.size();j++) maxleft[j]=max(maxleft[j-1],height[j]);
  8.         for(int j=height.size()-2;j>=0;j--) maxright[j]=max(maxright[j+1],height[j]);
  9.         for(int i=0;i<height.size();i++){
  10.             if(i==0||i==height.size()-1continue;
  11.             int mywater=min(maxleft[i],maxright[i])-height[i];
  12.             if(mywater>0) sum+=mywater;
  13.         }
  14.         return sum;
  15.     }
  16. };

单调栈:

一旦形成槽,就要计算接水量,所以从栈顶部到栈底,应当是维护递增。

注意是按行计算。

  1. class Solution {
  2. public:
  3.     int trap(vector<int>& height) {
  4.         int sum=0;
  5.         stack<int> s;
  6.         s.push(0);
  7.         for(int i=1;i<height.size();i++){
  8.             if(height[i]<height[s.top()]) s.push(i);
  9.             else if(height[i]==height[s.top()]){
  10.                 s.pop();
  11.                 s.push(i);
  12.             }
  13.             else{
  14.                 while(!s.empty()&&height[i]>height[s.top()]){
  15.                     int mid=s.top();
  16.                     s.pop();
  17.                     if(!s.empty()){
  18.                         int h=min(height[i],height[s.top()])-height[mid];
  19.                         int w=i-s.top()-1;
  20.                         int mywater=h*w;
  21.                         if(mywater>0) sum+=mywater;
  22.                         //按行计算,所以下一句还不能做pop();
  23.                     }
  24.                 }
  25.                 //记得入栈
  26.                 s.push(i);
  27.             }
  28.         }
  29.         return sum;
  30.     }
  31. };

正好二刷,单调栈写法:

  1. class Solution {
  2. public:
  3.     int trap(vector<int>& height) {
  4.         int sum=0;
  5.         stack<int> s;
  6.         s.push(0);
  7.         for(int i=1;i<height.size();i++){
  8.             while(!s.empty()&&height[i]>height[s.top()]){
  9.                 int mid=s.top();
  10.                 s.pop();
  11.                 if(!s.empty()){
  12.                     int h=min(height[i],height[s.top()])-height[mid];
  13.                     int w=i-s.top()-1;
  14.                     if(w*h>0) sum+=(w*h);
  15.                 }
  16.             }
  17.             s.push(i);
  18.         }
  19.         return sum;
  20.     }
  21. };

你可能会好奇:为什么while 里面的if要去计算宽度呢?不是按行计算吗?

因为外层是while,i不更新,却一直在弹出并计算水量。所以宽度不一定是1,宽度是动态变化的(根据栈的弹出。)

84柱状图中最大的矩形,困难

最后一题了,以后都是二刷或者做类似的题型。

因为每次只在一个柱子上搜结果,不累加,期望尽量搜到最大结果。

那么应当:往i的左边找最矮在哪,往i的右边找最矮的在哪(这些都要高于或等于i)。若左右有矮于i的,就不往那边搜(因为这样搜到的结果必定小于等于其他矮柱子搜到的结果,画图就知道了)。跨度*高度就是i搜到的矩形结果。

知道上述思路,就可以写算法去实现了。

朴素(超时):

  1. class Solution {
  2. public:
  3.     int largestRectangleArea(vector<int>& heights) {
  4.         int res=0;
  5.         for(int i=0;i<heights.size();i++){
  6.             int left=i,right=i;
  7.             for(;left>=0;left--){
  8.                 if(heights[left]<heights[i]) break;
  9.             }
  10.             for(;right<heights.size();right++){
  11.                 if(heights[right]<heights[i]) break;
  12.             }
  13.             int w=right-left-1;
  14.             int h=heights[i];
  15.             res=max(res,h*w);
  16.         }
  17.         return res;
  18.     }
  19. };

双指针写法比较复杂,不管了。

单调栈:与“接雨水”不一样的是,这题最左边和最右边柱子都有相应的结果,在接雨水里不是这样。为了普适性,我们需要把heights数组开头及末尾加入元素0.

你可能会好奇:为什么while 里面的if要去计算宽度呢?并且能实现题意呢?

因为外层是while,i不更新,却一直在弹出并计算面积。所以间距不一定是1,间距是动态变化的(根据栈的弹出。)

  1. class Solution {
  2. public:
  3.     int largestRectangleArea(vector<int>& heights) {
  4.         int res=0;
  5.         stack<int> s;
  6.         s.push(0);
  7.         heights.insert(heights.begin()+0,0);
  8.         heights.push_back(0);
  9.         for(int i=1;i<heights.size();i++){
  10.             while(!s.empty()&&heights[i]<heights[s.top()]){
  11.                 int mid=s.top();
  12.                 s.pop();
  13.                 if(!s.empty()){
  14.                     int left=s.top();
  15.                     int right=i;
  16.                     int w=right-left-1;
  17.                     int h=heights[mid];
  18.                     res=max(res,h*w);
  19.                 }
  20.             }
  21.             s.push(i);
  22.         }
  23.         return res;
  24.     }
  25. };

感谢支持,之后会写的其他的东西。

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

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

相关文章

node 中间件使用例子

NodeJS在中间件领域有着较为广泛的应用&#xff0c;他能做一些中间层事件&#xff0c;把服务端一部分的代码抽出来&#xff0c;减少处理冗余事情付出的代价&#xff0c;同时让服务真正做业务处理而不用关心页面的事情 常见的应用场景有&#xff1a; 跨域&#xff1a;解决跨域问…

二叉树左右树交换

leetcode 226题 翻转二叉树 题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3]…

背就有效!2024下《系统架构设计师》50个高频考点汇总

宝子们&#xff01;上半年软考已经结束一段时间了&#xff0c;准备备考下半年软考高级-系统架构设计师的小伙伴可以开始准备了&#xff0c;毕竟高级科目的难度可是不低的&#xff0c;相信参加过上半年架构的小伙伴深有体会。 这里给大家整理了50个高频考点&#xff0c;涵盖全书…

node更改npm缓存存储位置-并配置环境变量

更改缓存位置 node安装完成之后,在安装目录中新建一个存放缓存的文件夹node_cache 此时这个文件夹必须使用管理员权限才能更改,这使得命令行下使用npm进行下载的时候总是报权限不足的错误:permit 解决办法: 右键 -> 属性 -> 安全 -> 编辑 -> 选择user -> …

【Linux】进程_3

文章目录 五、进程3. 进程4. 进程状态 未完待续 五、进程 3. 进程 在当前&#xff0c;我们只能通过执行可执行程序来让操作系统帮我们启动进程&#xff0c;那我们如何使用代码来自己启动进程呢&#xff1f;我们可以使用 fork() 函数。作用是创建子进程。 我们创建一个程序来…

字节扣子搭建大模型擂台:匿名PK效果,用户当裁判,跑分时代要结束了

字节跳动的扣子&#xff08;coze.cn&#xff09;&#xff0c;给国产大模型们组了个大局—— 在同一个“擂台”上&#xff0c;两个大模型为一组&#xff0c;直接以匿名的方式PK效果&#xff01; 例如我们对两位参赛“选手”同时提问今年高考的题目&#xff1a; 阅读下面的材料&…

探索数字化转型:提升企业客户服务竞争力的策略

当前&#xff0c;数字经济已成为引领经济发展的“主引擎”。在这一背景下&#xff0c;客户服务领域也在发生着深刻变化&#xff0c;传统的以客服热线、人工客服为核心的客户服务模式已不能满足企业发展的需要&#xff0c;而数字化转型成为企业寻求突破的必然选择。 企业可利用大…

OpenAI把GPT-4原始版给了他们:研究不微调只靠提示词能走多远

除了OpenAI自己&#xff0c;居然还有别人能用上GPT-4-Base版&#xff1f;&#xff1f; 也就是未经微调的预训练版&#xff0c;还不会对话聊天&#xff0c;只会补全句子的模型。 EPFL&#xff08;瑞士洛桑联邦理工&#xff09;团队申请到了访问权限&#xff0c;用于研究**“上…

HCIE-QOS流量监管-拥塞管理

QOS流量监管-拥塞管理 QOS数据处理流程流量限速技术-令牌桶技术单桶单速双色标记法双桶单速三色标记法&#xff08;常用&#xff09;双桶双速三色标记法 流量监管承诺访问速率流量监管使用场景配置基于接口的流量监管配置MQC实现流量监管 流量整形流量整形的实现 (1)流量整形的…

LeetCode | 21.合并两个有序链表

这道题也是很经典的一道题了&#xff0c;408的算法题中也考过这个思想&#xff0c;因为两个链表已是升序&#xff0c;合并只需要两个指针&#xff0c;分别指向两个表的表头&#xff0c;分别比较两个指针所指向的结点的val&#xff0c;小的就插入到目标链表里面&#xff0c;再后…

鸿蒙轻内核Kconfig使用笔记

鸿蒙轻内核使用Kconfig进行图形化配置&#xff0c;本文专门讲解下鸿蒙轻内核LiteOS-M和LiteOS-A的图形化配置方法。本文中所涉及的源码&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 、 https://gitee.com/openharmony/kernel_liteos_m 获取。本…

交友系统定制版源码 相亲交友小程序源码全开源可二开 打造独特的社交交友系统

交友系统源码的实现涉及到多个方面&#xff0c;包括前端页面设计、后端逻辑处理、数据库设计以及用户交互等。以下是一个简单的交友系统源码实现的基本框架和关键步骤: 1.数据库设计:用户表:存储用户基本信息&#xff0c;如用户ID、用户名、密码、头像、性别、年龄、地理位置…

【我是产品经理_注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

go匿名函数

【1】Go支持匿名函数&#xff0c;如果我们某个函数只是希望使用一次&#xff0c;可以考虑使用匿名函数 【2】匿名函数使用方式&#xff1a; &#xff08;1&#xff09;在定义匿名函数时就直接调用&#xff0c;这种方式匿名函数只能调用一次&#xff08;用的多&#xff09; &am…

【推荐系统简介以及其链路流程】

文章目录 1、数据收集和预处理1.1、推荐系统的数据架构 2、用户&#xff08;user&#xff09;画像和物品&#xff08;item&#xff09;画像的构建3、特征工程3.1、特征提取的框架3.1.1、物料画像3.1.2、用户画像3.1.3、交叉特征3.1.4、偏差特征 3.2、数值特征的处理3.2.1、缺失…

数据更新-插入元组(VALUES)、修改属性(SET)、删除元组(DELETE)

一、插入元组 1、插入单个元组&#xff08;使用的是VALUES子句&#xff09; &#xff08;1&#xff09;语句格式 INSERT INTO <表名> 【&#xff08;<属性名1【&#xff0c;<属性名2>&#xff0c;...】&#xff09;】 VALUES &#xff08;<常量1>【&a…

后端项目实战--瑞吉外卖项目软件说明书

瑞吉外卖项目软件说明书 一、项目概述 瑞吉外卖项目是一个外卖服务平台&#xff0c;用户可以通过该平台浏览餐厅菜单、下单、支付以及追踪订单状态。产品原型就是一款产品成型之前的一个简单的框架&#xff0c;就是将页面的排版布局展现出来&#xff0c;使产品得初步构思有一…

有哪些常用ORM框架

ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;是一种编程技术&#xff0c;它允许开发者使用面向对象的编程语言来操作关系型数据库。ORM的主要目的是将数据库中的数据表映射到编程语言中的对象&#xff0c;从而使得开发者可以使用对象的方式来…

Android面试题之ActivityManagerService的启动流程

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 SystemServer启动 创建SystemContex 用于加载系统相关的资源&#xff0c;比如theme&#xff0c;android命名空间下的资源等创建引导服务&#…

02 Pytorch_NLP

1. N-gram n决定关联信息 2. TF____IDF TF&#xff1a;词频 IDF&#xff1a;逆向序列 假如&#xff1a;TF * IDF 就是当前的文件&#xff0c;那么乘积反而更大&#xff01; 因为它只出现在 特定的文章中&#xff01; TF-IDF 简介 TF-IDF&#xff08;Term Frequency-Inverse…