当前位置: 首页 > news >正文

[Algorithm][贪心][整数替换][俄罗斯套娃信封问题]详细讲解

目录

  • 1.整数替换
    • 1.题目链接
    • 2.算法原理详解
      • 1.解法一
      • 2.解法二
    • 3.代码实现
      • 1.代码一
      • 2.代码二
  • 2.俄罗斯套娃信封问题
    • 1.题目链接
    • 2.算法原理详解
      • 1.解法一
      • 2.解法二
    • 3.代码实现
      • 1.代码一
      • 2.代码二


1.整数替换

1.题目链接

  • 整数替换

2.算法原理详解

1.解法一

  • 思路:模拟(递归 + 记忆化搜索)
    请添加图片描述

2.解法二

  • 思路:贪心
    • 偶数:只能执行/2操作
    • 奇数:分类讨论
      请添加图片描述

3.代码实现

1.代码一

class Solution 
{unordered_map<int, int> hash;
public:int integerReplacement(int n) {return DFS(n);}int DFS(long long n){if(hash.count(n)){return hash[n];}if(n == 1){hash[1] = 0;return 0;}if(n % 2 == 0){hash[n] = 1 + DFS(n / 2);}else{hash[n] = 1 + min(DFS(n - 1), DFS(n + 1));}return hash[n];}
};

2.代码二

int integerReplacement(int n) 
{int ret = 0;while(n > 1){if(n % 2 == 0){n /= 2;ret++;}else{if(n == 3){ret += 2;n = 1;}else if(n % 4 == 1){n = n / 2; // -> (n - 1) / 2ret += 2;}else{n = n / 2 + 1; // -> (n + 1) / 2 -> 防溢出ret += 2;}}}return ret;
}

2.俄罗斯套娃信封问题

1.题目链接

  • 俄罗斯套娃信封问题

2.算法原理详解

  • 知识储备:最长递增子序列 --> 动态规划 + 贪心 + 二分

1.解法一

  • 解法:常规解法(通用解法) -> 动态规划(该题会超时)
    • 思考历程:乱序 --> 有序 --> 按照左端点排序 --> 最长递增子序列
    • 思路
      • 状态表示dp[i]:以i位置的信封为结尾的所有套娃序列中,最长的套娃序列的长度

      • 状态转移方程
        请添加图片描述

      • 返回值dp表中的最大值


2.解法二

  • 思路:重写排序 + 贪心 + 二分
    • 重写排序:此时,问题完全转化为最长递增子序列
      • 左端点不同时:左端点从小到大排序
      • 左端点相同时:右端点从大到小排序

3.代码实现

1.代码一

int maxEnvelopes(vector<vector<int>>& e) 
{sort(e.begin(), e.end());int n = e.size();vector<int> dp(n, 1);int ret = 1;for(int i = 1; i < n; i++){for(int j = 0; j < i; j++){if(e[i][0] > e[j][0] && e[i][1] > e[j][1]){dp[i] = max(dp[i], dp[j] + 1);}}ret = max(ret, dp[i]);}return ret;
}

2.代码二

int maxEnvelopes(vector<vector<int>>& e) 
{// 重写排序sort(e.begin(), e.end(), [&](const vector<int>& v1, const vector<int>& v2){return v1[0] != v2[0] ? v1[0] < v2[0] : v1[1] > v2[1];});// 贪心 + 二分vector<int> ret;ret.push_back(e[0][1]);for(int i = 1; i < e.size(); i++){int b = e[i][1];if(b > ret.back()){ret.push_back(b);}else{int left = 0, right = ret.size() - 1;while(left < right){int mid = (left + right) / 2;if(ret[mid] >= b){right = mid;}else{left = mid + 1;}}ret[left] = b;}}return ret.size();
}

http://www.mrgr.cn/news/45832.html

相关文章:

  • Day44【最短路+欧拉回路】
  • HeidiSQL 数据库密码如何恢复
  • 告别@Value,Spring Boot 3.3更优雅的配置注入方案
  • linux自动挂载tf卡
  • Spring系列 Bean创建过程
  • Kubernetes 深度探索:StatefulSet 之有状态应用实战
  • React Route v6. 如何防止用户导航到另一个页面
  • 数据结构-4.6.KMP算法(旧版下)-朴素模式匹配算法的优化
  • aws(学习笔记第四课) AWS的IAM服务,用于授权的策略,用户和组以及角色
  • docker compose入门5—创建一个3副本的应用
  • ◇【论文_20181020 v6】广义优势估计器 (generalized advantage estimator, GAE)
  • PicGo 配置 GitHub 作为后端存储,打造免费的图床工具
  • 知识改变命运 数据结构【java对象的比较】
  • Kubernetes 深度洞察:StatefulSet 之存储状态探秘
  • 多模态方法总结
  • 车辆重识别(2021NIPS无分类器扩散指南)论文阅读2024/10/08
  • 前端开发中的高级技巧与最佳实践
  • [Python学习日记-42] Python 中的生成器
  • 【计算机毕设】springboot-考研资讯平台(附源码)
  • 大数据新视界 --大数据大厂之 Hudi 数据湖框架性能提升:高效处理大数据变更