目录
一、前言
二、什么是字典序 ?
✨字典序概念
✨深度理解字典序
✨字典序排序的重要性和应用场景
三、常考面试题
✨ 下一个排列
✨ 字典数排序
✨ 字典序最小回文串
四、共勉
经常刷算法题的朋友,肯定会经常看到题目中提到 字典序 这样的字眼,或者需要我们通过字典序来解题,由于之前对字典序了解的不太清楚,导致做题的时候总会卡住,所以收集了一些资料来详解字典序。
字典序(dictionary order),又称 字母序(alphabetical order),含义是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。
举例:
在字典中,单词是按照首字母在字母表中的顺序进行排列的,比如 alpha 在 beta 之前。而第一个字母相同时,会去比较两个单词的第二个字母在字母表中的顺序,比如 account 在 advanced 之前,以此类推。下列单词就是按照字典序进行排列的:
as aster astrolabe astronomy astrophysics at ataman attack baa 举例:
对数字 【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】 总结:
对于两个不同的字符串,从左到右逐个比较它们的字符,
- 如果在某个位置上它们的字符不同,则将它们按照该位置上的字符的字母顺序进行排序,即较小的字符排在前面,较大的字符排在后面。
- 如果一直比较到其中一个字符串结束,则较短的字符串排在前面;
- 如果两个字符串完全相同,则它们的字典序相同。可以将它们看作是按照字母表的顺序进行排列的。
- 数据库索引:在数据库中,使用字典序排序可以加快查询速度。例如,对存储了字符串数据的列进行字典序排序,可以使得数据库在执行字符串比较操作时更高效。
- 字符串比较:在字符串比较场景中,字典序排序能够方便地判断两个字符串的大小关系。例如,在编程中,可以使用字典序排序来实现字符串的字母顺序排序、查找最大/最小字符串等操作。
- 文件系统排序:文件系统通常使用字典序排序来显示文件和目录的顺序。这样可以使得用户在文件浏览器中更容易找到特定的文件或目录。
通过上面的讲解,相信大家应该对 字典序 有了一个基础的了解,想要深刻的理解它,还是需要通过题目来理解。
链接:31. 下一个排列 - 力扣(LeetCode)

题目分析:
1,2,3 ------> 1,3,2来说明:上面从直觉上理解了什么是字典序算法,下面说下怎么转化成程序算法。
何时无解
首先考虑无解情况,即上面所说的321,这种情况带入字典序算法是无解的,而321这种情况,如果我们单独拆分成3,2,1三个数字,其实是一个降序的过程:

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

1. 从右往左找,找到第一个右边比左边大的数
2. 找到断点右边所有数中最小的一个 (包括断点)
3.交换左边的黄点和红点

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

代码:
class Solution { public: void nextPermutation(vector& 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[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 lexicalOrder(int n) { vector 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。
代码:
class Solution { public: string makeSmallestPalindrome(string s) { // 双指针 分别指向 头部和尾部 int begin = 0,end = s.size()-1; while(begin 以下就是我对 字典序 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 C++ 的更新,请持续关注我哦!!!
