当前位置:网站首页>去除重复字母[贪心+单调栈(用数组+len来维持单调序列)]
去除重复字母[贪心+单调栈(用数组+len来维持单调序列)]
2022-07-04 12:51:00 【REN_林森】
前言
当设计到最字问题时,多半涉及了贪心算法,这种情况,要自己去理解贪心过程,然后再体现在代码中。
当涉及到相对有序/前后大小之类的,一般就需要用单调栈来做维护,常见场景:往回比往回对冲。
对于单调栈/hash之类,能用数组的情况,还是可以用数组,在JVM层面,确实比API层面快很多,而且简洁轻量。
一、去除重复字母
二、贪心+单调栈
1、stack
// 取出重复字符串
public class RemoveDuplicateLetters {
/* target:去除重复字母,需要返回结果的字典序最小。 当s[i] >= s[i+1]且s[i]有又多的情况下,则把s[i]替换成‘#’号,然后s[i - 1]如果有的话,也要和s[i+1]比较。 这种往回比的感觉,属实是单调栈一类思想了。 */
public String removeDuplicateLetters(String s) {
char[] arr = s.toCharArray();
// 记录每个字符有多少个。
int[] fx = new int[26];
for (char c : arr) fx[c - 'a']++;
// 去重。
Stack<Character> sk = new Stack<>();
int[] set = new int[26];
for (int i = 0; i < arr.length; i++) {
// 把前面大的,且后面还有重复的字符,就消除掉,尽可能让前面保持单调,即使不单调,那个字符肯定是只有1个。
while (!sk.isEmpty() && sk.peek() > arr[i] && fx[sk.peek() - 'a'] != 1 && set[arr[i] - 'a'] == 0) {
System.out.println(fx[sk.peek() - 'a']);
--fx[sk.peek() - 'a'];
set[sk.pop() - 'a'] = 0;
}
// 把新字符加入,如果新字符前面已经加入过了,就不用加这个了,毕竟相同的小字符尽量放到前面最小。
if (set[arr[i] - 'a'] == 0) {
// 加入单调栈中没有,且和单调栈中字符成相对单调的字符。
sk.push(arr[i]);
// 设置其已在单调栈中存在。
set[arr[i] - 'a'] = 1;
} else --fx[arr[i] - 'a'];// 需要去除的字符,所以个数需要减1
}
// 把相对单调的字符组合成单调字符串。
StringBuilder sb = new StringBuilder();
while (!sk.isEmpty()) sb.insert(0, sk.pop());
return sb.toString();
}
public static void main(String[] args) {
new RemoveDuplicateLetters().removeDuplicateLetters("abafdsfasfasdfasdfasdfasfsdagewha");
}
}
2、原生数组+len替代stack
// 大胆尝试,用数组替换栈。
// 果然,原生数组是真的快。
class RemoveDuplicateLetters2 {
/* target:去除重复字母,需要返回结果的字典序最小。 当s[i] >= s[i+1]且s[i]有又多的情况下,则把s[i]替换成‘#’号,然后s[i - 1]如果有的话,也要和s[i+1]比较。 这种往回比的感觉,属实是单调栈一类思想了。 */
public String removeDuplicateLetters(String s) {
char[] arr = s.toCharArray();
// 记录每个字符有多少个。
int[] fx = new int[26];
for (char c : arr) fx[c - 'a']++;
// 去重。
char[] sk = new char[s.length()];
int skLen = 0;
int[] set = new int[26];
for (int i = 0; i < arr.length; i++) {
// 把前面大的,且后面还有重复的字符,就消除掉,尽可能让前面保持单调,即使不单调,那个字符肯定是只有1个。
while (skLen != 0 && sk[skLen - 1] > arr[i] && fx[sk[skLen - 1] - 'a'] != 1 && set[arr[i] - 'a'] == 0) {
System.out.println(fx[sk[skLen - 1] - 'a']);
--fx[sk[skLen - 1] - 'a'];
set[sk[--skLen] - 'a'] = 0;
}
// 把新字符加入,如果新字符前面已经加入过了,就不用加这个了,毕竟相同的小字符尽量放到前面最小。
if (set[arr[i] - 'a'] == 0) {
// 加入单调栈中没有,且和单调栈中字符成相对单调的字符。
sk[skLen++] = arr[i];
// 设置其已在单调栈中存在。
set[arr[i] - 'a'] = 1;
} else --fx[arr[i] - 'a'];// 需要去除的字符,所以个数需要减1
}
// 把相对单调的字符组合成单调字符串。
StringBuilder sb = new StringBuilder();
while (skLen != 0) sb.insert(0, sk[--skLen]);
return sb.toString();
}
}
总结
1)涉及最字,联想贪心知识点;涉及有序/前后大小类,联想单调栈知识点。
2)数组hash/数组模拟栈,比起HashMap/Stack类,要快很多,就像原生堆排序比优先队列快一样。
参考文献
[1] LeetCode 去除重复字母
边栏推荐
- gorm 之数据插入(转)
- 读取 Excel 表数据
- [antd] how to set antd in form There is input in item Get input when gourp Value of each input of gourp
- Golang uses JSON unmarshal number to interface{} number to become float64 type (turn)
- 30: Chapter 3: develop Passport Service: 13: develop [change / improve user information, interface]; (use * * * Bo class to accept parameters, and use parameter verification)
- Understand chisel language thoroughly 04. Chisel Foundation (I) - signal type and constant
- MySQL 5 installation and modification free
- Ws2811 m is a special circuit for three channel LED drive and control, and the development of color light strip scheme
- Can mortgage with housing exclude compulsory execution
- Basic mode of service mesh
猜你喜欢
MySQL 5 installation and modification free
30: Chapter 3: develop Passport Service: 13: develop [change / improve user information, interface]; (use * * * Bo class to accept parameters, and use parameter verification)
sharding key type not supported
【Antd踩坑】Antd Form 配合Input.Group时出现Form.Item所占据的高度不对
使用默认路由作为指向Internet的路由
Interviewer: what is the internal implementation of hash data type in redis?
Unittest框架中引入TestFixture
392. 判断子序列
Doctoral application | West Lake University Learning and reasoning system laboratory recruits postdoctoral / doctoral / research internship, etc
Unittest中的TestSuite和TestRunner
随机推荐
【Antd】Antd 如何在 Form.Item 中有 Input.Gourp 时获取 Input.Gourp 的每一个 Input 的value
R语言使用dplyr包的group_by函数和summarise函数基于分组变量计算目标变量的均值、标准差
Learning projects are self-made, and growth opportunities are self created
R语言使用lattice包中的bwplot函数可视化箱图(box plot)、par.settings参数自定义主题模式
Five "potential errors" in embedded programming
[R language data science]: cross validation and looking back
Introducing testfixture into unittest framework
Install MySQL
Use the default route as the route to the Internet
Understand chisel language thoroughly 06. Chisel Foundation (III) -- registers and counters
2022g3 boiler water treatment examination question simulation examination question bank and simulation examination
国内酒店交易DDD应用与实践——代码篇
392. 判断子序列
Ruichengxin micro sprint technology innovation board: annual revenue of 367million, proposed to raise 1.3 billion, Datang Telecom is a shareholder
Dgraph: large scale dynamic graph dataset
Install Trinity and solve error reporting
测试流程整理(3)
mac redis安装与使用,连接远程服务器 redis
China Post technology rushes to the scientific innovation board: the annual revenue is 2.058 billion, and the postal group is the major shareholder
Understand chisel language thoroughly 03. Write to the developer of Verilog to chisel (you can also see it without Verilog Foundation)