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

【算法】贪心算法:最大数C++

文章目录

  • 前言
  • 题目解析
  • 算法原理
    • 字典序
  • 代码示例
  • 策略证明

前言

题目的链接,大家可以先试着去做一下再来看一下思路。179. 最大数 - 力扣(LeetCode)

题目解析

还是老样子,把题目读懂,画出有用信息。

在这里插入图片描述

认真看示例,要好好去想一下,特殊示例的情况。

在这里插入图片描述

算法原理

在这里插入图片描述

字典序

插个小曲,介绍一下字典序。

  1. 概念:
    字典序(LexicographicalOrder),也称为词典序、字母序或词典顺序,是一种基于字符顺序的字符串比较方法。它类似于我们在字典中查找单词的顺序。
  2. 字符编码基础
    字典序依赖于字符的编码系统:
    ASCII:‘0’=48, ‘1’=49, …, ‘9’=57, ‘A’=65, ‘B’=66, …, ‘a’=97, ‘b’=98, …
    Unicode:包含更多字符,但数字和字母的顺序与ASCII一致。
  3. 比较规则
    字典序的核心规则是从左到右逐字符比较:

比较第一个字符: 如果字符不同,则根据字符的编码值(如ASCII或Unicode)决定顺序;编码值小的字符串排在前面 。
例一: “apple” vs “banana” → “apple” < “banana”(因为 ‘a’<‘b’);

如果第一个字符相同:比较第二个字符;依此类推,直到找到不同的字符。
例二:“dat” vs “dog” → “dat” < “dog”(因为’a’<‘o’)

所有字符都相同: 较短的字符串排在较长的字符串前面。
例三:“hello” vs “hell” → “hell” <“hello”(相同前缀,较短者优先)

  1. 示例解析

数字字符串比较:
“2” vs “10” → “10” < “2”(因为 ‘1’<‘2’)
“30” vs “4” → “30” <“4”(因为 ‘3’<‘4’)
“100” vs “2” → “100” < “2”(因为 ‘1’<‘2’)
混合比较:
“file9” vs “file10” → “file10” < “file9”(因为 ‘1’<‘9’)
“item2” vs “item10” → “item10” < “item2”(因为 ‘1’<‘2’)

  1. 在本代码中的应用
    在largestNumber算法中(largestNumber 算法通常指的是如何将一组非负整数重新排列,使得它们拼接后的数字是最大的。),我们使用字典序比较拼接后的字符串为什么有效呢。
//这行代码是自定义排序比较逻辑的核心,它决定了两个字符串在排序时的相对顺序。
//如果 s1 + s2 组成的字符串更大,返回 true,表示 s1 应该排在 s2 前面。
//如果 s2 + s1 更大,返回 false,表示 s2 应该排在 s1 前面。
return s1 + s2 > s2 + s1;

长度相等:s1+s2和s2+s1长度相同(len(s1)+len(s2))
字典序等价数值序:当两个数字字符串长度相同时,字典序大小关系等同于数值大小关系。

  1. 字典序与数值序的区别
比较方式“2” vs “10”“30” vs “4”“100” vs “2”
字典序“10” < “2”“30” < “4”“100” < “2”
数值序10 > 230 > 4100 > 2

字典序:基于字符编码从左到右比较.。
数值序:基于实际数值大小比较。

  1. 在算法中的重要性

在本问题中,使用字典序比较拼接字符串是高效的,因为:
避免了大数计算(拼接后可能超出整数范围) 。
利用字符串比较的内置优化。
当长度相同时,保持数值大小关系。

  1. 总结

字典序是一种基于字符编码顺序的字符串比较方法:
从左到右逐字符比较。
编码值小的字符排在前。
相同前缀时较短字符串排在前。
在等长数字字符串比较中等价于数值比较。

代码示例

class Solution {
public:string largestNumber(vector<int>& nums){//优化一下,把所有的整数转化为字符串,我们用字典序去比较,比直接转换整形比较好很多,vector<string> str;for(auto x : nums) str.push_back(to_string(x));//排序,拼接字符串,比较字典序。当两个数字字符串长度相同时,字典序大小关系等同于数值大小关系。//标准库的 sort 通常使用快速排序,这类比较排序算法的核心是通过多次比较和交换元素位置来达到有序。sort(str.begin(),str.end(),[](const string &s1, const string &s2){return s1 + s2 > s2 + s1;});//提取结果string ret;for(auto &s : str) ret += s;//特殊情况,数组中全是0不能返回"000...",应该返回"0"if(ret[0] == '0') return "0";return ret; }
};

策略证明

证明方法:全序关系

全序关系(Total Order)是指在一个集合X上,满足以下三个条件的二元关系:
完全性:对于集合中的任意两个元素a和b,要么a ≤ b,要么b ≤ a 。
反对称性:如果a ≤ b且b ≤ a,则a = b。
传递性:如果a ≤ b且b ≤ c,则a ≤ c。
全序关系也称为线性序或简单序。一个具有全序关系的集合称为全序集。
例如,实数集上的小于等于关系(≤)就是一个全序关系,因为任意两个实数都可以比较大小。

假设定义了集合{a,b,c,d,e,f,g},我从集合中任意挑选两个元素,如果这两个元素在你定义的比较规则下,满足全序关系的话,我们就说这个集合是可以排序的。
只要满足下面三个性质,就有全序关系。
1.完全性,2.反对称性,3.传递性

我们接下来就要去证明我们算法原理中的自定义排序是否有效。
在这里插入图片描述

http://www.dtcms.com/a/279127.html

相关文章:

  • Linux 音频的基石: ALSA
  • 【云服务器安全相关】如何使用 `ping` 命令排查云服务器网络连接问题
  • javascript自执行函数
  • Retinex视网膜算法(SSR、MSR、MSRCR)
  • DNS重绑定
  • 纯净系统清理工具,告别卡顿烦恼
  • iOS高级开发工程师面试——RunTime
  • 构建完整工具链:GCC/G++ + Makefile + Git 自动化开发流程
  • 数字影像产业新机遇 入驻国际数字影像产业园享151项服务
  • 【人工智能】通过 Dify 构建智能助手
  • Day34 Java方法05 可变参数
  • JavaScript中Object.defineProperty的作用和用法以及和proxy的区别
  • 优化菜品呈现:让菜品自己 “开口” 求传播
  • 【ASP.NET Core】内存缓存(MemoryCache)原理、应用及常见问题解析
  • 我的Qt八股文笔记2:Qt并发编程方案对比与QPointer,智能指针方案
  • 电气安全监测系统:筑牢电气安全防线
  • DAOS系统架构-Container
  • 壹[1],异步与多线程
  • 美联储降息趋缓叠加能源需求下调,泰国证券交易所新一代交易系统架构方案——高合规、强韧性、本地化的跨境金融基础设施解决方案
  • 【Linux】Ubuntu22.04安装zabbix
  • 固态金属储氢实用化提速:新氢动力 20 公斤级系统重磅发布
  • GaussDB in的用法
  • Linux部署Mysql
  • JavaScript进阶篇——第一章 作用域与垃圾回收机制
  • Netty编程模型介绍
  • 每天学习一个Python库之os库
  • Debezium日常分享系列之:Debezium 3.2.0.Final发布
  • MySQL Innodb Cluster配置
  • Ubuntu服务器安装Miniconda
  • VS2019编译使用log4cplus 1.2.0