字典序是指从前到后比较两个字符串大小的方法。首先比较第1个字符,如果不同则第1个字符较小的字符串更小,一直这样子比较下去。
比如:
s1:ABCDE 和 s2:ABCCE 两个字符串,s1的 D 比 s2的 C要更加大一点,所以s1 > s2。
现在有这样一个问题,
给定长度为N的字符串S,要构造一个长度为 N 的字符串 T。起初 ,T 是一个空串,随后反复进行下列任意操作,
- 从 S 的头部删除一个字符,加到 T 的尾部。
- 从 S 的尾部删除一个字符,加到 T 的尾部。
目标是构造字典序最小的字符串 T。
这类题型一般利用贪心来做,贪心就是就是遵循某种规则,不断贪心地选取当前的最优策略的算法。
每做出的一步选择都是当前的最优策略,并不需要考虑整体,但难点就在于当前最优策略的选择,拿上面那道题继续分析,
要创建字典序最小的字符串T,我们只需要保证字符串的前面尽量较小,所以每次从字符串 S 的首尾取相对较小的加入到字符串 T 中,这就是策略,但这个策略还可能遇到一个问题,如果当首尾的字符此时相等的话,该如何选择?这时候就要比较下一个了,选择下一个字符里面相对较小的加入到字符串 T 中。这两者结合就是我们的贪心策略。
有点懵?
不急,我们来看看图解。
假定给定的字符串 S = “ACDBCB”,
一开始,两指针指向字符串 S 的首尾,比较两者的大小,将小的一位加入到字符串 T 中,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KPUXSQU8-1587397993732)(https://note.youdao.com/yws/api/personal/file/WEB3456d3793d40c320734e1ed8a5f21870?method=download&shareKey=02b9e33205368bdc04735cace3be3592)]](https://img-blog.csdnimg.cn/20200420235340857.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmdlcnhpYW8xMjEyMjM=,size_16,color_FFFFFF,t_70#pic_center)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6x9Ulh0e-1587397993735)(https://note.youdao.com/yws/api/personal/file/WEBac8970a5de087e54f280c4a526c55e4b?method=download&shareKey=e83798b44b36054879de800e2e1aebbb)]](https://img-blog.csdnimg.cn/2020042023535240.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmdlcnhpYW8xMjEyMjM=,size_16,color_FFFFFF,t_70#pic_center)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JFAaqBhe-1587397993738)(https://note.youdao.com/yws/api/personal/file/WEB51ddf14e2f9cc1246a1de464f72cde7b?method=download&shareKey=23bbeaccb17dbf86e0f321cb774de00d)]](https://img-blog.csdnimg.cn/20200420235400972.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmdlcnhpYW8xMjEyMjM=,size_16,color_FFFFFF,t_70#pic_center)
此时两指针对应的字符相等,这时候要判断下一位的大小,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4nM19tbw-1587397993743)(https://note.youdao.com/yws/api/personal/file/WEB1dc5c524e818afbf2fb7dee7b3d6144a?method=download&shareKey=9e06ae44b3b788c1d8373bf3868c5159)]](https://img-blog.csdnimg.cn/20200420235412164.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmdlcnhpYW8xMjEyMjM=,size_16,color_FFFFFF,t_70#pic_center)
B < D,所以将右侧的先加入,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j20yUjD3-1587397993746)(https://note.youdao.com/yws/api/personal/file/WEB0cb4f8b41d3b817730c5180d659245d0?method=download&shareKey=d7ca2ee4470c4d9cf7a03883be814783)]](https://img-blog.csdnimg.cn/20200420235423555.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmdlcnhpYW8xMjEyMjM=,size_16,color_FFFFFF,t_70#pic_center)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQZ2nMCq-1587397993748)(https://note.youdao.com/yws/api/personal/file/WEB679ae8133d4ba32acf96e0686f2979fc?method=download&shareKey=b2bd484581b93e0478165cb2ce3f106e)]](https://img-blog.csdnimg.cn/20200420235432121.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmdlcnhpYW8xMjEyMjM=,size_16,color_FFFFFF,t_70#pic_center)

应该够清晰了吧,那么我们可以写一下伪代码了,伪代码主要是总结以上思路,以便更好的转换成最终代码。
# String S;
# String T;
# left, right
while(left <= right) {
如果左边较小,将左边加入T;
如果右变较小,将右边加入T;
if(相等) {
i = left + 1;
j = right - 1;
while(i <= j) {
如果左边较小,将左边加入T;
如果右变较小,将右边加入T;
if(相等)
i++;
j--;
}
}
}
好,以上应该都比较好理解了,那可以直接转成我们的代码了。
class Solution {
public String bestCowLine(String S) {
String T = "";
int left = 0;
int right = S.length() - 1;
char[] temp = S.toCharArray();
//左右两指针,向中间移动
while(left <= right) {
//标记左边是否小过右边
boolean l = false;
//如果左右两边一致,就跳出循环,不一致就一直寻找
for(int i = 0; left + i <= right; i++) {
//如果左边小于右边,标记并跳出
if(temp[left + i] < temp[right - i]) {
l = true;
break;
}
//如果右边小于左边,标记并跳出
else if(temp[left + i] > temp[right - i]) {
l = false;
break;
}
}
//加入到字符串 T 中
if(left == true)
T += temp[left++];
else
T += tempS[right--];
}
return T;
}
}
整理于 2020.4.19
版权声明:本文为wangerxiao121223原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。