当前位置:网站首页>去除重複字母[貪心+單調棧(用數組+len來維持單調序列)]
去除重複字母[貪心+單調棧(用數組+len來維持單調序列)]
2022-07-04 14:14: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 去除重複字母
边栏推荐
- 国内酒店交易DDD应用与实践——代码篇
- 常见 content-type对应表
- MySQL version 8 installation Free Tutorial
- Migration from go vendor project to mod project
- Understand chisel language thoroughly 04. Chisel Foundation (I) - signal type and constant
- IDEA快捷键大全
- 吃透Chisel语言.05.Chisel基础(二)——组合电路与运算符
- C# wpf 实现截屏框实时截屏功能
- What is the real meaning and purpose of doing things, and what do you really want
- 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
猜你喜欢

MySQL8版本免安装步骤教程

Product identification of intelligent retail cabinet based on paddlex

Unittest框架中引入TestFixture

吃透Chisel语言.11.Chisel项目构建、运行和测试(三)——Chisel测试之ScalaTest

Detailed explanation of Fisher information quantity detection countermeasure sample code

CVPR 2022 | 大幅减少零样本学习所需的人工标注,提出富含视觉信息的类别语义嵌入(源代码下载)...

中邮科技冲刺科创板:年营收20.58亿 邮政集团是大股东

吃透Chisel语言.10.Chisel项目构建、运行和测试(二)——Chisel中生成Verilog代码&Chisel开发流程

学内核之三:使用GDB跟踪内核调用链

MySQL version 8 installation Free Tutorial
随机推荐
以房抵债能否排除强制执行
奇妙秘境 码蹄集
2022危险化学品经营单位主要负责人练习题及模拟考试
Unittest框架之断言
Use the default route as the route to the Internet
gorm 之数据插入(转)
Code hoof collection of wonderful secret place
QT how to detect whether the mouse is on a control
吃透Chisel语言.05.Chisel基础(二)——组合电路与运算符
C# wpf 实现截屏框实时截屏功能
markdown 语法之字体标红
find命令报错: paths must precede expression(转)
海外游戏代投需要注意的
【R语言数据科学】:交叉验证再回首
Detailed explanation of Fisher information quantity detection countermeasure sample code
程序员的焦虑
2022游戏出海实用发行策略
392. 判断子序列
Yingshi Ruida rushes to the scientific and Technological Innovation Board: the annual revenue is 450million and the proposed fund-raising is 979million
qt 怎么检测鼠标在不在某个控件上