当前位置:网站首页>去除重复字母[贪心+单调栈(用数组+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 去除重复字母
边栏推荐
- The mouse wheel of xshell/bash/zsh and other terminals is garbled (turn)
- 2022 hoisting machinery command examination simulation 100 questions simulation examination platform operation
- Assertion of unittest framework
- Ruichengxin micro sprint technology innovation board: annual revenue of 367million, proposed to raise 1.3 billion, Datang Telecom is a shareholder
- 测试流程整理(2)
- Doctoral application | West Lake University Learning and reasoning system laboratory recruits postdoctoral / doctoral / research internship, etc
- 吃透Chisel语言.04.Chisel基础(一)——信号类型和常量
- Unity Shader学习(三)试着绘制一个圆
- Yingshi Ruida rushes to the scientific and Technological Innovation Board: the annual revenue is 450million and the proposed fund-raising is 979million
- Understand chisel language thoroughly 03. Write to the developer of Verilog to chisel (you can also see it without Verilog Foundation)
猜你喜欢

【Antd】Antd 如何在 Form.Item 中有 Input.Gourp 时获取 Input.Gourp 的每一个 Input 的value

sharding key type not supported

One of the solutions for unity not recognizing riders

JVM memory layout detailed, illustrated, well written!

205. 同构字符串

1200. 最小绝对差

MySQL5免安装修改

基于PaddleX的智能零售柜商品识别

Detailed explanation of Fisher information quantity detection countermeasure sample code

CVPR 2022 | 大幅减少零样本学习所需的人工标注,提出富含视觉信息的类别语义嵌入(源代码下载)...
随机推荐
2022 practice questions and mock exams for the main principals of hazardous chemical business units
Basic mode of service mesh
Can mortgage with housing exclude compulsory execution
Test evaluation of software testing
Ruichengxin micro sprint technology innovation board: annual revenue of 367million, proposed to raise 1.3 billion, Datang Telecom is a shareholder
Deming Lee listed on Shenzhen Stock Exchange: the market value is 3.1 billion, which is the husband and wife of Li Hu and Tian Hua
Understand chisel language thoroughly 12. Chisel project construction, operation and testing (IV) -- chisel test of chisel test
Product identification of intelligent retail cabinet based on paddlex
吃透Chisel语言.06.Chisel基础(三)——寄存器和计数器
Error in find command: paths must precede expression (turn)
What is the real meaning and purpose of doing things, and what do you really want
PHP log debugging
吃透Chisel语言.08.Chisel基础(五)——Wire、Reg和IO,以及如何理解Chisel生成硬件
markdown 语法之字体标红
Introducing testfixture into unittest framework
mac redis安装与使用,连接远程服务器 redis
Golang 使用 JSON unmarshal 数字到 interface{} 数字变成 float64 类型(转)
Hardware Basics - diode Basics
R语言使用lattice包中的bwplot函数可视化箱图(box plot)、par.settings参数自定义主题模式
Variable promotion and function promotion in JS