leetcode :316 Remove Duplicate Letters : 贪心+递归搜索

来源:互联网 发布:手机工程算量软件 编辑:程序博客网 时间:2024/06/10 02:58

316. Remove Duplicate Letters

My Submissions
Total Accepted: 11048 Total Submissions: 44956 Difficulty: Hard

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"









贪心+搜索:字符串全是字母,一共26个。每个字母都有它出现的位置,可能0个,可能多个。想要子串使得字母序最小且每个出现的字母只出现一次。那么:针对出现过的字母,从字典序按个安排位置,只要按照出现顺序都能安排下,就搜索到一个子串满足要求。

我的方法:使用数组保存26个字母出现的位置,每个字母出现的位置使用优先权队列保存,方便。。。(后来也发觉并没有什么卵用)。然后使用数组availItem表示字母是否可以被安排,使用数组maxIndex表示字母所能被安排的最大的位置(方便判断能否安排来减枝)。直到搜索到所有出现的字母都被安排即可。

public class Solution {    public int findLine(Object[] objects,int lastIndex){int min=Integer.MAX_VALUE;for(int i=0;i<objects.length;i++){if((int)objects[i]>lastIndex&&(int)objects[i]<min)min=(int)objects[i];}return min;}public boolean linereach(int findline,int[] availItem,int[] maxIndex){for(int i=0;i<26;i++){if(availItem[i]==1&&maxIndex[i]<findline)return false;}return true;}public char[] search(ArrayList<PriorityQueue<Integer>> graph,int[] availItem,int[] maxIIndex,char[] reTemp,int x,int avialCount,int lastIndex){if(x>=avialCount)return reTemp;for(int i=0;i<26;i++){if(availItem[i]==1){int findline=findLine(graph.get(i).toArray(),lastIndex);if(linereach(findline,availItem,maxIIndex)){availItem[i]=0;reTemp[x]=(char) ('a'+i);char[] tt=search(graph, availItem, maxIIndex, reTemp, x+1, avialCount, findline);if(tt!=null)return tt;availItem[i]=1;}}}return null;}public String removeDuplicateLetters(String s) {ArrayList<PriorityQueue<Integer>> graph = new ArrayList<>();for (int i = 0; i < 26; i++)graph.add(new PriorityQueue<>());int[] availItem = new int[26];int[] maxIndex = new int[26];for (int i = 0; i < 26; i++)maxIndex[i] = availItem[i] = 0;int availCount = 0;for (int i = 0; i < s.length(); i++) {int itemNum = s.charAt(i) - 'a';graph.get(itemNum).add(i);if (availItem[itemNum] == 0) {availItem[itemNum] = 1;availCount++;}maxIndex[itemNum] = maxIndex[itemNum] < i ? i : maxIndex[itemNum];}char[] reTemp = new char[26];reTemp = search(graph, availItem, maxIndex, reTemp, 0, availCount,-1);return String.valueOf(reTemp,0,availCount);}}

他们的代码真tm精炼。。。。代码的思路,本质上是一样的。

不过时间没我的快(10ms),嘻嘻~(他们的23ms)

public class Solution {    public String removeDuplicateLetters(String s) {        int[] cnt = new int[26];        int pos = 0; // the position for the smallest s[i]        for (int i = 0; i < s.length(); i++) cnt[s.charAt(i) - 'a']++;        for (int i = 0; i < s.length(); i++) {            if (s.charAt(i) < s.charAt(pos)) pos = i;            if (--cnt[s.charAt(i) - 'a'] == 0) break;        }        return s.length() == 0 ? "" : s.charAt(pos) + removeDuplicateLetters(s.substring(pos + 1).replaceAll("" + s.charAt(pos), ""));    }}




0 0
原创粉丝点击