当前位置:网站首页>去除重複字母[貪心+單調棧(用數組+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 去除重複字母
边栏推荐
- Use the default route as the route to the Internet
- Unittest框架中引入TestFixture
- Unity shader learning (3) try to draw a circle
- Haobo medical sprint technology innovation board: annual revenue of 260million Yonggang and Shen Zhiqun are the actual controllers
- How to choose a technology stack for web applications in 2022
- 1200. Minimum absolute difference
- Basic mode of service mesh
- Blob, text geometry or JSON column'xxx'can't have a default value query question
- MySQL 5 installation and modification free
- 测试流程整理(2)
猜你喜欢
Applet live + e-commerce, if you want to be a new retail e-commerce, use it!
MySQL8版本免安装步骤教程
华昊中天冲刺科创板:年亏2.8亿拟募资15亿 贝达药业是股东
Doctoral application | West Lake University Learning and reasoning system laboratory recruits postdoctoral / doctoral / research internship, etc
Test evaluation of software testing
392. 判断子序列
硬件基础知识-二极管基础
Unity shader learning (3) try to draw a circle
吃透Chisel语言.06.Chisel基础(三)——寄存器和计数器
Understand chisel language thoroughly 11. Chisel project construction, operation and test (III) -- scalatest of chisel test
随机推荐
Dgraph: large scale dynamic graph dataset
392. 判断子序列
R语言使用dplyr包的group_by函数和summarise函数基于分组变量计算目标变量的均值、标准差
锐成芯微冲刺科创板:年营收3.67亿拟募资13亿 大唐电信是股东
2022危险化学品经营单位主要负责人练习题及模拟考试
The mouse wheel of xshell/bash/zsh and other terminals is garbled (turn)
[FAQ] Huawei Account Service Error Report 907135701 Common reasons Summary and Solutions
以房抵债能否排除强制执行
Understand chisel language thoroughly 05. Chisel Foundation (II) -- combinational circuits and operators
Understand chisel language thoroughly 03. Write to the developer of Verilog to chisel (you can also see it without Verilog Foundation)
Worried about "cutting off gas", Germany is revising the energy security law
Unittest框架中引入TestFixture
吃透Chisel语言.09.Chisel项目构建、运行和测试(一)——用sbt构建Chisel项目并运行
基于PaddleX的智能零售柜商品识别
Hardware Basics - diode Basics
R语言使用lattice包中的bwplot函数可视化箱图(box plot)、par.settings参数自定义主题模式
吃透Chisel语言.03.写给Verilog转Chisel的开发者(没有Verilog基础也可以看看)
MySQL5免安装修改
Huahao Zhongtian sprint Technology Innovation Board: perte annuelle de 280 millions de RMB, projet de collecte de fonds de 1,5 milliard de Beida Pharmaceutical est actionnaire
golang fmt. Printf() (turn)