当前位置:网站首页>去除重复字母[贪心+单调栈(用数组+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 去除重复字母
边栏推荐
- Error in find command: paths must precede expression (turn)
- [antd] how to set antd in form There is input in item Get input when gourp Value of each input of gourp
- Understand chisel language thoroughly 07. Chisel Foundation (IV) - bundle and VEC
- Golang 使用 JSON unmarshal 数字到 interface{} 数字变成 float64 类型(转)
- File creation, writing, reading, deletion (transfer) in go language
- IP lab monthly resumption · issue 5
- Gorm read / write separation (rotation)
- Understand chisel language thoroughly 04. Chisel Foundation (I) - signal type and constant
- Assertion of unittest framework
- 自主工业软件的创新与发展
猜你喜欢
测试流程整理(2)
Huahao Zhongtian rushes to the scientific and Technological Innovation Board: the annual loss is 280million, and it is proposed to raise 1.5 billion. Beida pharmaceutical is a shareholder
Mask wearing detection based on yolov1
吃透Chisel语言.09.Chisel项目构建、运行和测试(一)——用sbt构建Chisel项目并运行
markdown 语法之字体标红
Summary of recent days (non-technical article)
学内核之三:使用GDB跟踪内核调用链
国内酒店交易DDD应用与实践——代码篇
英视睿达冲刺科创板:年营收4.5亿 拟募资9.79亿
TestSuite and testrunner in unittest
随机推荐
Fs7867s is a voltage detection chip used for power supply voltage monitoring of digital system
Understanding and difference between viewbinding and databinding
吃透Chisel语言.05.Chisel基础(二)——组合电路与运算符
Qt如何实现打包,实现EXE分享
Understand chisel language thoroughly 07. Chisel Foundation (IV) - bundle and VEC
使用默认路由作为指向Internet的路由
Learning projects are self-made, and growth opportunities are self created
華昊中天沖刺科創板:年虧2.8億擬募資15億 貝達藥業是股東
sharding key type not supported
Yingshi Ruida rushes to the scientific and Technological Innovation Board: the annual revenue is 450million and the proposed fund-raising is 979million
[antd step pit] antd form cooperates with input Form The height occupied by item is incorrect
【FAQ】华为帐号服务报错 907135701的常见原因总结和解决方法
IDEA快捷键大全
Hardware Basics - diode Basics
R语言使用dplyr包的group_by函数和summarise函数基于分组变量计算目标变量的均值、标准差
吃透Chisel语言.06.Chisel基础(三)——寄存器和计数器
Gorm read / write separation (rotation)
30: Chapter 3: develop Passport Service: 13: develop [change / improve user information, interface]; (use * * * Bo class to accept parameters, and use parameter verification)
Unity Shader学习(三)试着绘制一个圆
学内核之三:使用GDB跟踪内核调用链