LeetCode 316. Remove Duplicate Letters(删除重复字母)
来源:互联网 发布:淘宝怎么把顾客拉黑 编辑:程序博客网 时间:2024/06/05 14:10
原题网址:https://leetcode.com/problems/remove-duplicate-letters/
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"
方法一:逐个字母找出。例如要找出第一个字母,首先找到最右边的一个点,使该点右边能够包含全部的字母,则第一个字母必在该点左边(包含该点),寻找方法是从该点向左搜寻,搜寻到一个字母表最靠前的、位置最靠左的字母,则为第一个字母。
public class Solution { public String removeDuplicateLetters(String s) { char[] sa = s.toCharArray(); int[] alphabet = new int[26]; int count = 0; for(int i=0; i<sa.length; i++) { if (alphabet[sa[i]-'a']==0) count ++; alphabet[sa[i]-'a'] ++; } char[] removed = new char[count]; int left = 0; int right = sa.length; int c = 0; Arrays.fill(alphabet, 0); while (c<count) { right --; if (alphabet[sa[right]-'a']==0) c ++; alphabet[sa[right]-'a'] ++; } for(int i=0; i<count; i++) { char ch = sa[right]; int leftmost=right; for(int j=right-1; j>=left; j--) { if (sa[j] <= ch && alphabet[sa[j]-'a'] != 0) { ch = sa[j]; leftmost = j; } } alphabet[ch-'a'] = 0; removed[i] = ch; left = leftmost + 1; while (right<sa.length-1 && alphabet[sa[right]-'a'] != 1) { if (alphabet[sa[right]-'a'] > 1) alphabet[sa[right]-'a'] --; right ++; } } return new String(removed); }}
另一种实现:
public class Solution { public String removeDuplicateLetters(String s) { int[] f = new int[26]; char[] sa = s.toCharArray(); int count = 0; for(int i=sa.length-1; i>=0; i--) { if (f[sa[i]-'a'] == 0) count ++; f[sa[i]-'a'] ++; } char[] unique = new char[count]; Arrays.fill(unique, (char)0xff); int from = 0, to = 0; int pos = 0; for(int i=0; i<count; i++) { while (to<sa.length && (f[sa[to]-'a']!=1)) f[sa[to++]-'a']--; for(int j=from; j<=to; j++) { if (f[sa[j]-'a']>0 && sa[j] < unique[i]) { unique[i] = sa[j]; pos = j; } } while (pos+1<to) f[sa[--to]-'a']++; f[unique[i]-'a'] = 0; from = pos + 1; to = from; } return new String(unique); }}
又一个实现:
public class Solution { public String removeDuplicateLetters(String s) { if (s == null || s.length() == 0) return s; char[] sa = s.toCharArray(); int[] f = new int[26]; int len = 0; for(int i=0; i<sa.length; i++) { if (f[sa[i]-'a'] ++ == 0) len ++; } char[] unique = new char[len]; int from = 0; for(int i=0; i<unique.length; i++) { int right = from; int pos = -1; while (right < sa.length && f[sa[right++]-'a']-- != 1); for(int j=from; j<right; j++) { if (f[sa[j]-'a'] >= 0 && (pos==-1 || sa[j]<sa[pos])) pos = j; } unique[i] = sa[pos]; for(int j=pos; j<right; j++) { f[sa[j]-'a'] ++; } f[sa[pos]-'a'] = 0; from = pos + 1; } return new String(unique); }}
方法二:使用堆。
public class Solution { public String removeDuplicateLetters(String s) { char[] sa = s.toCharArray(); int[] f = new int[26]; int count = 0; // 统计不同的字符个数 for(char ch : sa) { if (f[ch - 'a']++ == 0) count++; } char[] result = new char[count]; PriorityQueue<Character> heap = new PriorityQueue<>(); int i = 0; int from = 0, to = 0; while (i < result.length) { // 找到最大可能靠后的候选字符位置 while (to < sa.length) { if (f[sa[to] - 'a'] > 0) { heap.offer(sa[to]); if (--f[sa[to++] - 'a'] == 0) break; } else { to++; } } char ch = (char)0; do { ch = heap.poll(); while (heap.remove(ch)); result[i++] = ch; f[ch - 'a'] = 0; // 该字符前面的字符已经作废,从堆中删除 while (sa[from++] != ch) { heap.remove(sa[from - 1]); } // 如果最大可能靠后的候选字符已经被选择,则终止 } while (ch != sa[to - 1]); } return new String(result); }}
方法三:使用二叉搜索树。
public class Solution { int size = 0; int[] set = new int[26]; int[] tree = new int[26]; private void offer(int val) { int i = 0, j = 25; while (i <= j) { int m = (i + j) >> 1; if (m < val) { i = m + 1; } else { tree[m] ++; j = m - 1; } } size ++; set[val]++; } private boolean remove(int val) { if (size == 0 || set[val] == 0) return false; int i = 0, j = 25; while (i <= j) { int m = (i + j) >> 1; if (m < val) { i = m + 1; } else { tree[m] --; j = m - 1; } } size--; set[val]--; return true; } private int min() { int i = 0, j = 25; while (i <= j) { int m = (i + j) >> 1; if (tree[m] > 0) { tree[m] --; j = m - 1; } else { i = m + 1; } } size--; set[i]--; return i; } public String removeDuplicateLetters(String s) { char[] sa = s.toCharArray(); int[] f = new int[26]; int count = 0; // 统计不同的字符个数 for(char ch : sa) { if (f[ch - 'a']++ == 0) count++; } char[] result = new char[count]; int i = 0; int from = 0, to = 0; while (i < result.length) { // 找到最大可能靠后的候选字符位置 while (to < sa.length) { if (f[sa[to] - 'a'] > 0) { offer(sa[to] - 'a'); if (--f[sa[to++] - 'a'] == 0) break; } else { to++; } } char ch = (char)0; do { ch = (char)('a' + min()); while (remove(ch - 'a')); result[i++] = ch; f[ch - 'a'] = 0; // 该字符前面的字符已经作废,从搜索树中删除 while (sa[from++] != ch) { remove(sa[from - 1] - 'a'); } // 如果最大可能靠后的候选字符已经被选择,则终止 } while (from < to && ch != sa[to - 1]); } return new String(result); }}
0 0
- LeetCode 316. Remove Duplicate Letters(删除重复字母)
- Leetcode 316. Remove Duplicate Letters
- Leetcode 316. Remove Duplicate Letters
- leetcode 316. Remove Duplicate Letters
- 316. Remove Duplicate Letters LeetCode
- LeetCode 316. Remove Duplicate Letters
- leetcode.316. Remove Duplicate Letters
- LeetCode 316. Remove Duplicate Letters
- [leetcode]316. Remove Duplicate Letters
- leetcode 316. Remove Duplicate Letters
- leetcode 316. Remove Duplicate Letters
- leetcode 316. Remove Duplicate Letters
- leetcode Remove Duplicate Letters
- leetcode: Remove Duplicate Letters
- LeetCode Remove Duplicate Letters
- 《leetCode》:Remove Duplicate Letters
- Leetcode: Remove Duplicate Letters
- leetcode--Remove Duplicate Letters
- 掌握 Dojo 工具包,第 8 部分: 明日之星 - DojoX
- 掌握 Dojo 工具包,第 9 部分: Dojo 国际化
- win10屏幕亮度无法调整的原因
- Leetcode 231. Power of Two & 326. Power of Three & 342. Power of Four
- 284. Peeking Iterator
- LeetCode 316. Remove Duplicate Letters(删除重复字母)
- cdh集群安装(提高)
- ZOJ(ZJU) 1002 Fire Net(深搜)
- flask路由与反路由
- C++ 线程操作
- C51 禁止使用绝对寄存器寻址方式访问函数选定
- iBatis SqlMap的配置总结
- Linux编程(文件描述符)
- 深夜课堂:JavaScript简介