【算法】字典序超详细解析(让你有一种相见恨晚的感觉!)

目录

一、前言

二、什么是字典序 ?

✨字典序概念

✨深度理解字典序

✨字典序排序的重要性和应用场景

 三、常考面试题

 ✨ 下一个排列

 ✨ 字典数排序

 ✨ 字典序最小回文串

 四、共勉


一、前言

    经常刷算法题的朋友,肯定会经常看到题目中提到 字典序 这样的字眼,或者需要我们通过字典序来解题,由于之前对字典序了解的不太清楚,导致做题的时候总会卡住,所以收集了一些资料来详解字典序。

二、什么是字典序 ?

 ✨字典序概念

    字典序(dictionary order),又称 字母序(alphabetical order),含义是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。 

 举例:
       在字典中,单词是按照首字母在字母表中的顺序进行排列的,比如 alphabeta 之前。而第一个字母相同时,会去比较两个单词的第二个字母在字母表中的顺序,比如 accountadvanced 之前,以此类推。下列单词就是按照字典序进行排列的:

as

aster

astrolabe

astronomy

astrophysics

at

ataman

attack

baa

✨深度理解字典序

  • 在学习 字符串string 的时候,我们肯定接触过两个字符串之间的比较,比如”abc“ < “acb” < “acbd”, 其规则是先比较第一个字母,如果不相等,就直接得到结果,如果相等,就比较下一个字母。
  • 如果两个字符串的长度不相等,但是长的那个字符串包含了短的那个,那长的那个字符串更大(比如"acb" < “acbd”)
  • 在我们进行比较之前,有一个默认的排序规则,就是‘a' < 'b' < 'c' < ... < 'z'

举例:

对数字 【1,2,3,4,5,6,7,8,9,10,11,12,13】 按照字典序排列:
结果为 :【1,10,11,12,13,2,3,4,5,6,7,8,9】 

总结: 
      对于两个不同的字符串,从左到右逐个比较它们的字符,

  1. 如果在某个位置上它们的字符不同,则将它们按照该位置上的字符的字母顺序进行排序,即较小的字符排在前面,较大的字符排在后面。
  2. 如果一直比较到其中一个字符串结束,则较短的字符串排在前面;
  3. 如果两个字符串完全相同,则它们的字典序相同。可以将它们看作是按照字母表的顺序进行排列的。

 ✨字典序排序的重要性和应用场景

  1. 数据库索引:在数据库中,使用字典序排序可以加快查询速度。例如,对存储了字符串数据的列进行字典序排序,可以使得数据库在执行字符串比较操作时更高效。
  2. 字符串比较:在字符串比较场景中,字典序排序能够方便地判断两个字符串的大小关系。例如,在编程中,可以使用字典序排序来实现字符串的字母顺序排序、查找最大/最小字符串等操作。
  3. 文件系统排序:文件系统通常使用字典序排序来显示文件和目录的顺序。这样可以使得用户在文件浏览器中更容易找到特定的文件或目录。

 三、常考面试题

      通过上面的讲解,相信大家应该对 字典序 有了一个基础的了解,想要深刻的理解它,还是需要通过题目来理解。

 ✨ 下一个排列

链接:31. 下一个排列 - 力扣(LeetCode) 

 题目分析:

  • 说实话刚看题目我看了半天不知道在说什么,看到评论里面提到字典序算法才知道题意。我们拿题目中的例子1,2,3 ------> 1,3,2来说明:
  1. 首先本题讨论的范围是数字,数字中有一个规则,就是’0‘ < '1' < '2' < ... < '9',这与上面的a~z是一样的
  2. 然后就是1,2,3这三个数字,我们能够形成6种不同的组合,即123 < 132 < 213 < 231 < 312 < 321。
  3. OK,如果你看懂前面两点,本题已经完成了。我们要做的就是找到当前数 123 在第二点的六种排列中间的下一个位置是什么,即 132,那么 132 就是答案
  4. 如果要找的数字位于排列组合的最后一个一位,即 321,那么按照题目的第二行,我们就返回最小值 123.

上面从直觉上理解了什么是字典序算法,下面说下怎么转化成程序算法。

何时无解 

首先考虑无解情况,即上面所说的321,这种情况带入字典序算法是无解的,而321这种情况,如果我们单独拆分成3,2,1三个数字,其实是一个降序的过程: 

  • 因此如果当前排列是降序的,则字典序算法无解
  • 换而言之,如果不存在后一个数比前一个数大(2<3,1<2),字典序算法无解
  • 比如下图中的54321抽象出来的五个点,不存在后一个点大于前一个点,因此无解。

 有解的情况

 下面我们拿51432这个例子,来一步步说明如何通过字典序算法得到 52134 这个答案的

 1. 从右往左找,找到第一个右边比左边大的数

  • 首先我们从最右边的2开始,因为2 < 3,因此跳过。然后3 < 4,再跳过。然后发现4 > 1,OK,第一步完成。
  • 然后我们在上图中用黄色点标记这两个数,即1 和 4

2. 找到断点右边所有数中最小的一个 (包括断点)

  • 如果我们直接交换两个黄点,得到 54132,虽然也比 51432 大,但是它不符合字典序算法中的规则,因为这两个数中间还夹杂着别的数 51432 < 52134 < 52143 < 52314 < ...... < 54132,字典序算法中必须满足两个数之间不能夹杂其他数才行。
  • 而根据上面列举的,我们知道 52134 才是我i们想要的答案,它的特点就是我们需要把 1 换成2,而不是 4。
  • 而 2 实际上就是4,3,2中间的最小值,因此这一步我们要做的就是找到左边黄点(1)右边的所有数(4,3,2)中间最小的一个数(2),然后我们用 红点标记下来。
  • 之所以要交换1和2,而不是1和3或者1和4,是因为我们现在是要把千位的1换成一个更大中的最小的情况,因此要选2.

3.交换左边的黄点和红点 

  •  上面我们找到了红点(2),因此这一步我们需要讲红点跟左边的黄点(2)进行交换,得到52431

4. 对红点右边的数进行升序排序 

  • 此时,我们交换了千位的1和个位2,变成了52431.但是距离我们的最终答案52134还差了一步,52134 < 52143 < 52314 < 52341 < 52413 < 52431,👈由这个规则可以看到我们的千位和万位已经相同了,但是个十百位还未相同了,而因为我们要找的答案要尽可能小,因此需要进行升序排序,得到52134,大功告成!

 代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) 
    {
        // 用于判断是否无解  -- 开始默认无解
          bool flag = 0;
        for(int i = nums.size()-1;i>0;i--)
        {
            if(nums[i]>nums[i-1])
            {
                // 有解
                flag = 1;
                // 初始化最小值 为右边断点 
                int min = nums[i],idx = i;
                // 向后找最小值
                for(int j = i+1;j<nums.size();j++)
                {
                    if(nums[j]<min && nums[j] > nums[i-1])
                    {
                        // 更新最小值
                        min = nums[j];
                        // 存储小标,便于后续交换
                        idx = j;
                    }
                }

                // 将右边最小值 和 左边最小值交换  (左右区分,以断点为界线)
                nums[i - 1]^= nums[idx];
                nums[idx]^= nums[i - 1];      // 小技巧  位运算  不用第三个参数来交换两个数
                nums[i - 1]^= nums[idx];

                // 将左边的数据 包括断点进行升序排序
                sort(nums.begin()+i,nums.end());
                break;
            }
        }
        // 确定误解  将动态数组全部进行 升序排序
        if(flag == 0)
        {
            sort(nums.begin(),nums.end());
        }
    }
};

 ✨ 字典数排序

 链接:386. 字典序排数 - 力扣(LeetCode)

class Solution {
public:
    static bool cmp(int a,int b)
    {
        string s1 = to_string(a);
        string s2 = to_string(b);
        // 字典升序
        return s1<s2;
    }
    vector<int> lexicalOrder(int n) 
    {
         vector<int> res;
         while(n!=0)
         {
            res.push_back(n);
            n--;
         }
         sort(res.begin(),res.end(),cmp);
         return res;
    }
};

 ✨ 字典序最小回文串

 链接:2697. 字典序最小回文串 - 力扣(LeetCode)

 题目分析:

     对于两个中心对称的字母 x = s[i] 和 y = s[ n - 1 - i ] , 如果 x != y ,那么只需要修改一次,就可以让这两个字母相同:把 x 改成 y 或者 把 y 改成 x。

  • 如果 x > y , 那么把 x 修改成 y 更好 , 这样字典序更小
  • 如果 x < y , 那么把 y 修改成 x 更好 , 这样字典序更小

 代码:

class Solution {
public:
    string makeSmallestPalindrome(string s) 
    {
        // 双指针 分别指向 头部和尾部
        int begin = 0,end = s.size()-1;

        while(begin<end)
        {
            if(s[begin]!=s[end])
            {
                s[begin] = s[end] = min(s[begin],s[end]);
            }
            begin++;
            end--;
        }
        return s;
    }
};

 四、共勉

  以下就是我对 字典序 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 C++ 的更新,请持续关注我哦!!! 

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

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

相关文章

AutoMQ 如何实现分区持续重平衡?

01 引言 在一个线上 Kafka 集群中&#xff0c;流量的波动、Topic 的创建和删除、Broker 的消亡和启动都随时可能发生&#xff0c;而这些变化可能导致流量在集群各个节点间分布不均&#xff0c;从而导致资源浪费、影响业务稳定。此时则需要主动将 Topic 的不同分区在各个节点间…

mysql 磁盘空间100%

MySQL大事务可能会导致过多的占用临时文件&#xff0c;导致磁盘空间撑满的问题 本例说明下binlog cache产生的临时文件 案例复现 调小binlog_cache_size&#xff0c;让DML使用临时文件 使用存储过程模拟大事务 创建表 create table t1( id int AUTO_INCREMENT, name varchar…

[蓝桥杯练习]通电

kruskal做法(加边) #include <bits/stdc.h> using namespace std; int x[10005],y[10005],z[10005];//存储i点的x与y坐标 int bcj[10005];//并查集 struct Edge{//边 int v1,v2; double w; }edge[2000005]; int cmp(Edge a, Edge b){return a.w < b.w;} int find(i…

视频素材库哪个网站最好?推荐六大视频素材库

大家好&#xff01;在视频创作的旅程中&#xff0c;找到一个好的视频素材库就像找到了一把打开宝藏的钥匙。那么&#xff0c;视频素材库哪个网站最好呢&#xff1f;今天&#xff0c;我要给大家推荐六个主流的视频素材分享网站&#xff0c;让你的视频制作更加轻松&#xff0c;在…

Goby 漏洞发布|浙大恩特客户资源管理系统 RegulatePriceAction SQL 注入漏洞

漏洞名称&#xff1a; 浙大恩特客户资源管理系统 RegulatePriceAction SQL 注入漏洞 English Name&#xff1a; Entsoft Duite Customer Resource Management System RegulatePriceAction API SQL Injection Vulnerability CVSS core: 9.3 影响资产数&#xff1a;10524 漏洞…

揭秘!自定义三维模型如何在RflySim中实现仿真(二)

一. 技术背景 揭秘&#xff01;自定义三维模型如何在RflySim中实现仿真&#xff08;一&#xff09; 上篇文章我们学习了自定义三维模型如何在RflySim中实现仿真&#xff0c;接下来要学习三维场景导入RflySim的实验&#xff1a;将UE4自带场景导入RflySim平台&#xff0c;熟悉从…

Vue项目中引入外部字体文件

1、导入字体文件&#xff08; .ttf格式&#xff09; 1.下载相应的字体文件&#xff0c;或者找ui设计师要一份。一般字体文件使用 .ttf 格式的即可。 将准备好的字体文件&#xff0c;放在项目中&#xff0c;文件目录示例如下&#xff1a; 2.创建一个font.css文件用于定义这个字…

zookeeper快速入门四:在java客户端中操作zookeeper

系列文章&#xff1a; zookeeper快速入门一&#xff1a;zookeeper安装与启动-CSDN博客 zookeeper快速入门二&#xff1a;zookeeper基本概念-CSDN博客 zookeeper快速入门三&#xff1a;zookeeper的基本操作 先启动zookeeper服务端。 在maven引入zookeeper依赖。 <depende…

C++项目——集群聊天服务器项目(十三)客户端登录、注册、退出业务

截止到上节&#xff0c;我们已将服务器端主要代码介绍完毕&#xff0c;由于不可能一直手动输入信息&#xff0c;所以我们还需编写客户端代码&#xff0c;进行双向通信。 客户端不要求高并发&#xff0c;因此我们这里不使用muduo网络库的TcpClient类编写&#xff0c;仅采用C自带…

ComplexHeatmap绘图:注释、图例、热图基础(自备)

目录 基础介绍 Heatmap绘图基础参数 数据 作图参数 Heatmap Annotations&#xff08;注释&#xff09; 基础注释设置 简单注释测试 anno_points散点注释 anno_lines连线注释 anno_barplot条形图 anno_boxplot箱线图 anno_histogram直方图 热图组合 基础组合 进行…

使用idea一次性删除java文件中所有的注释内容 /* */

将.class文件转成.java文件后&#xff0c;.java文件每行都会生成注释/* */&#xff0c;下面是通过idea的替换功能&#xff0c;使用正则表达式删除注释/* */。 我使用MacBook&#xff0c;commandR打开替换查找替换界面&#xff0c;第一步选中 .* &#xff0c;第二步在…

虚拟机与开发板之间互传文件、文件夹

1.配置桥接模式实现外网访问 1.1设置 VMnet0 要桥接的网卡 打开【编辑】-【虚拟网络编辑器】 选择【更改设置】 选择【VMnet0】&#xff0c;选择桥接到宿主机上的哪个网卡。 通过打开安装虚拟机的宿主机的【网络适配器】&#xff0c;可以查看网卡名称。 1.2虚拟机配置桥接模式…

Idea2023创建Servlet项目

① Java EE 只是一个抽象的规范&#xff0c;具体实现称为应用服务器。 ② Java EE 只需要两个包 jsp-api.jar 和 servlet-api.jar&#xff0c;而这两个包是没有官方版本的。也就是说&#xff0c;Java 没有提供这两个包&#xff0c;只提供了一个规范。那么这两个包是谁提供的…

Java23种常见设计模式汇总

七大原则网站地址&#xff1a;设计模式7大原则&#xff0b;类图关系-CSDN博客 创建型设计模式&#xff1a;创建型设计模式合集-CSDN博客 七大结构型设计模式&#xff1a;7大结构型设计模式-CSDN博客 11种行为型设计模式&#xff1a; 11种行为型模式&#xff08;上&#xff0…

Xmind安装在指定目录

场景&#xff1a; Xmind安装默认是安装C盘。 问题描述 一般用户都习惯将软件安装在其他盘&#xff0c;但是Xmind不支持安装的时候指定磁盘或目录。 解决方案&#xff1a; 1、在D盘创建一个文件夹&#xff0c;用于安装Xmind&#xff0c;比如创建一个D:\Program Files (x86)…

MyBatis动态SQL--if 标签

mybatis动态sql对我们来说是非常常见的&#xff0c;比如在下面这样一个场景中&#xff0c; 我们需要多条件查询&#xff0c;但是查询的条件又不是固定的&#xff0c;是可以动态改变的&#xff0c;那我们就需要用到动态sql去完成。 动态SQL之 if 标签 接下来我们介绍第一个动态…

【Java代码审计】S2-045 远程代码执行漏洞分析复现

【Java代码审计】S2-045 远程代码执行漏洞分析复现 1.漏洞原理2.靶场复现 1.漏洞原理 官方对该漏洞的描述是这样的&#xff1a;Struts2 默认处理 multipart 上传报文的解析器为 Jakarta 插件&#xff08;org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类&a…

基于opencv的SVM算法的车牌识别系统设计与实现

基于opencv的SVM算法的车牌识别系统设计与实现 车牌识别技术是智能交通系统中的一项关键技术&#xff0c;它能够自动识别车辆的车牌号码。本文将详细介绍如何使用Python编程语言结合OpenCV库和SVM算法来实现车牌识别系统。 系统架构 车牌识别系统主要包括以下几个模块&…

外贸建站:WordPress搭建外贸独立站零基础自建站完整教程(2024)

对于做外贸来说&#xff0c;拥有自己的外贸独立网站真的非常重要。在外贸领域&#xff0c;如今各平台竞争激烈&#xff0c;规则多&#xff0c;成本高&#xff0c;价格战、政策变化快&#xff0c;还存在封店风险等等因素。在这种情况下&#xff0c;拥有外贸独立站就能很好规避上…

JavaSE:抽象类和接口

目录 一、前言 二、抽象类 &#xff08;一&#xff09;抽象类概念 &#xff08;二&#xff09;使用抽象类的注意事项 &#xff08;三&#xff09;抽象类的作用 三、接口 &#xff08;一&#xff09;接口概念 &#xff08;二&#xff09;接口语法规则 &#xff08;三&a…