当前位置:网站首页>去除重複字母[貪心+單調棧(用數組+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 去除重複字母
边栏推荐
- 吃透Chisel语言.09.Chisel项目构建、运行和测试(一)——用sbt构建Chisel项目并运行
- 海外游戏代投需要注意的
- 【R语言数据科学】:交叉验证再回首
- 学内核之三:使用GDB跟踪内核调用链
- 205. 同构字符串
- find命令报错: paths must precede expression(转)
- MySQL version 8 installation Free Tutorial
- 【Matlab】conv、filter、conv2、filter2和imfilter卷积函数总结
- MySQL5免安装修改
- 吃透Chisel语言.12.Chisel项目构建、运行和测试(四)——Chisel测试之ChiselTest
猜你喜欢

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

Unittest中的TestSuite和TestRunner

C# wpf 实现截屏框实时截屏功能

Applet live + e-commerce, if you want to be a new retail e-commerce, use it!
![[FAQ] Huawei Account Service Error Report 907135701 Common reasons Summary and Solutions](/img/43/1a9786c89a5ab21d1fb8903cb7b77e.png)
[FAQ] Huawei Account Service Error Report 907135701 Common reasons Summary and Solutions

Interviewer: what is the internal implementation of hash data type in redis?

Install MySQL

MySQL之详解索引

测试流程整理(3)

TestSuite and testrunner in unittest
随机推荐
IDEA快捷键大全
安装Mysql
吃透Chisel语言.11.Chisel项目构建、运行和测试(三)——Chisel测试之ScalaTest
30: Chapter 3: develop Passport Service: 13: develop [change / improve user information, interface]; (use * * * Bo class to accept parameters, and use parameter verification)
Ws2818m is packaged in cpc8. It is a special circuit for three channel LED drive control. External IC full-color double signal 5v32 lamp programmable LED lamp with outdoor engineering
392. 判断子序列
Gorm data insertion (transfer)
【Matlab】conv、filter、conv2、filter2和imfilter卷积函数总结
Interview disassembly: how to check the soaring usage of CPU after the system goes online?
吃透Chisel语言.07.Chisel基础(四)——Bundle和Vec
Use the default route as the route to the Internet
如何游戏出海代运营、游戏出海代投
[antd] how to set antd in form There is input in item Get input when gourp Value of each input of gourp
华昊中天冲刺科创板:年亏2.8亿拟募资15亿 贝达药业是股东
Code hoof collection of wonderful secret place
Blob, text geometry or JSON column'xxx'can't have a default value query question
golang fmt. Printf() (turn)
Unittest框架之断言
392. Judgement subsequence
R语言使用dplyr包的group_by函数和summarise函数基于分组变量计算目标变量的均值、标准差