Remove Duplicate Letters(Java 递归与非递归)
题目介绍:
Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Example:
Given "bcabc"
Return "abc"
Given "cbacdcbc"
Return "acdb"
解题思路一:
这道题让我们移除重复字母,使得每个字符只能出现一次,而且结果要按字母顺序排,前提是不能打乱其原本的相对位置。我们的解题思路是:先建立一个哈希表来统计每个字母出现的次数,还需要一个visited数字来纪录每个字母是否被访问过,我们遍历整个字符串,对于遍历到的字符,先在哈希表中将其值减一,然后看visited中是否被访问过,若访问过则继续循环,说明该字母已经出现在结果中并且位置已经安排妥当。如果没访问过,我们和结果中最后一个字母比较,如果该字母的ASCII码小并且结果中的最后一个字母在哈希表中的值不为0(说明后面还会出现这个字母),那么我们此时就要在结果中删去最后一个字母且将其标记为未访问,然后加上当前遍历到的字母,并且将其标记为已访问,以此类推直至遍历完整个字符串s,此时结果里的字符串即为所求。这里有个小技巧,我们一开始给结果字符串res中放个"0",就是为了在第一次比较时方便,如果为空就没法和res中的最后一个字符比较了,而‘0’的ASCII码要小于任意一个字母的,所以不会有问题。最后我们返回结果时再去掉开头那个‘0’即可,参见代码如下:
public String removeDuplicateLetters(String s) {
            if(s == null)
                return null;
            else if (s.trim() == "") {
                return "";
            }
            String res = "0"; //存储结果
            Map<Character,Integer> map = new HashMap<Character, Integer>(); //记录各个字符出现的次数
            boolean[] visited = new boolean[256]; //记录字符是否已经被访问过
            //初始化map
            for (int i = 0; i < s.length(); i++) {
                char key = s.charAt(i);
                if(map.containsKey(key)){//若字符key已经存在,次数加1
                    map.put(key, map.get(key) + 1);
                } else {
                    map.put(key, 1);
                }
            }
            //遍历字符串s
            for(int i = 0; i < s.length(); i++){
                char key = s.charAt(i);
                map.put(key, map.get(key) - 1); //key的次数减1
                if(!visited[key]){ //若key尚未被访问过
                    for (int j = res.length() - 1; j >= 1; j--) { //遍历当前结果集中的每一个字符
                        char c = res.charAt(j); //取出当前结果中的最后一个字符
                        if(key < c && map.get(c) > 0){ //若当前遍历到的字符比res末尾字符小,且末尾字符在后面还会遍历到,则用key替换掉末尾的字符c,并将c设置为尚未访问过
                            visited[c] = false;
                            res = res.substring(0,res.length() - 1); //删除res中的最后一个字符
                        } else if(key > c){
                            break;
                        } else if(key < c && map.get(c) == 0){ //当前元素比c小,但是c在后面已经不会被遍历到了
                            break;
                        }
                    }
                    visited[key] = true;  //设置为已经被访问
                    res = res + key;
               }
            }
            return res.substring(1);
    }
解题思路二:(递归)
这道题如果用Java解题的话可以使用一种递归的方法。
先用哈希表记录每个字母出现的次数,再遍历给定字符串s,找出最小的字母,每比较一个字母,在哈希表中的值减1,如果此时为0了,
则不继续遍历了,此时我们记录了一个位置,把字符串s中该位置左边的字符都删掉,右边的所有再出现的该字母也删掉,递归调用此函数即可,
在Java中可以使用replace函数。
/**
* 递归方法求解res
* @param s
* @return
*/
public static String removeDuplicate_Recursively(String s){
if(s == null)
return null;
int len = s.length();
if(len == 0) return ""; /**存储字符及个数*/
Map<Character,Integer> map = new HashMap<Character,Integer>();
for(int i = 0;i < len;i++){
char c = s.charAt(i);
if(map.containsKey(c)){
map.put(c, map.get(c) + 1);
} else {
map.put(c, 1);
}
} //递归 /**记录最小字符及位置*/
char ch = s.charAt(0);
int pos = 0;
for(int i = 0;i < len;i++){ //遍历字符串s
char c = s.charAt(i);
/**更新最小字符*/
if(c < ch) {
ch = c;
pos = i;
}
/**只有一个字符,不能再减了。更新字符串,递归查找*/
if(map.get(c) == 1) {
s = s.substring(pos + 1).replaceAll(ch + "", "");
return ch + removeDuplicate_Recursively(s); //递归查找
} else {
map.put(c, map.get(c) - 1);
}
} return "";
}
Remove Duplicate Letters(Java 递归与非递归)的更多相关文章
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
		上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ... 
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
		前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ... 
- 二叉树3种递归和非递归遍历(Java)
		import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ... 
- JAVA递归、非递归遍历二叉树(转)
		原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ... 
- java扫描文件夹下面的所有文件(递归与非递归实现)
		java中扫描指定文件夹下面的所有文件扫描一个文件夹下面的所有文件,因为文件夹的层数没有限制可能多达几十层几百层,通常会采用两种方式来遍历指定文件夹下面的所有文件.递归方式非递归方式(采用队列或者栈实 ... 
- [LeetCode] Remove Duplicate Letters 移除重复字母
		Given a string which contains only lowercase letters, remove duplicate letters so that every letter ... 
- [LeetCode] 316. Remove Duplicate Letters 移除重复字母
		Given a string which contains only lowercase letters, remove duplicate letters so that every letter ... 
- LeetCode Remove Duplicate Letters
		原题链接在这里:https://leetcode.com/problems/remove-duplicate-letters/ 题目: Given a string which contains on ... 
- AJPFX:递归与非递归之间的转化
		在常规表达式求值中: 输入为四则运算表达式,仅由数字.+.-.*./ .(.) 组成,没有空格,要求求其值. 我们知道有运算等级,从左至右,括号里面的先运算,其次是* ./,再是+.- : 这样我们就 ... 
随机推荐
- 抠图|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
			样例输入: 3 4 5 1 0 0 0 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 5 6 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 0 0 ... 
- POJ 2400 Supervisor, Supervisee(KM二分图最大权值匹配)题解
			题意:n个老板n个员工,先给你n*n的数据,i行j列代表第i个老板第j喜欢的员工是谁,再给你n*n的数据,i行j列代表第i个员工第j喜欢的老板是谁,如果匹配到第k喜欢的人就会产生一个分数k-1.现在让 ... 
- Asp.Net 之 OnClientClick 与 OnClick 的执行顺序
			Asp.net 中 OnClientClick 与 OnClick 的执行顺序为:客户端的OnClientClick先执行,服务器端的OnClick后执行. 拓展:在执行完客户端的OnClientCl ... 
- log4j2日志xml配置——不同级别的日志分别记录在不同的文件
			<?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL ... 
- PTA 7-1 畅通工程之局部最小花费问题(35 分)
			7-1 畅通工程之局部最小花费问题(35 分) 某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的 ... 
- Mac   python  2.X   升级到 3.X
			Mac OS X10.9默认带了Python2.7,不过现在Python3.3.3出来了,如果想使用最新版本,赶紧升级下吧.基本步骤如下. 第1步:下载Python3.3 下载地址如下: Python ... 
- phpstorm软件配置端口问题
			phpstorm默认的端口号是:63342 但是我装的apache服务器的默认端口是80 网上查找资料,都说可以加listen的端口,比如这里 #Listen 12.34.56.78:80 Lis ... 
- ADO.NET DBHelper
			using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Da ... 
- Jquery loading 效果
			function showLoad(tipInfo) { var eTip = document.createElement('div'); eTip.setAttribute('id', 'tipD ... 
- codeforces gym 100971 K Palindromization 思路
			题目链接:http://codeforces.com/gym/100971/problem/K K. Palindromization time limit per test 2.0 s memory ... 
