Given string A representative a positive integer which has N digits, remove any k digits of the number, the remaining digits are arranged according to the original order to become a new positive integer. Make this new positive integers as small as possible. N <= 240 and k <=N, Example Given an integer A = 178542, k = 4 return a string "12"
第二遍做法:跟 Remove Duplicate Letters 和 Create Maximum Number很像
維護一個stack,每次把當前char加進去,直到加到A.length()-k個。加之前看看能不能刪一些棧頂元素,條件:
1. 棧非空
2. 當前元素<棧頂元素
3. A后面剩的元素數目 >= A.length()-k-stack.size()
這樣弄出來棧里面存着最后的數
注意可能以0開頭,沒關系,因為題目是刪掉元素剩的最小的數,允許的,只用最后返回結果把開頭0去掉就行
1 public class Solution { 2 /** 3 *@param A: A positive integer which has N digits, A is a string. 4 *@param k: Remove k digits. 5 *@return: A string 6 */ 7 public String DeleteDigits(String A, int k) { 8 // write your code here 9 if (k == 0) return A; 10 if (A == null || A.length()==0 || A.length()==k) return ""; 11 Stack<Character> stack = new Stack<Character>(); 12 int len = A.length()-k; 13 for (int i=0; i<A.length(); i++) { 14 char c = A.charAt(i); 15 while (!stack.isEmpty() && c<stack.peek() && A.length()-i-1>=len-stack.size()) { 16 stack.pop(); 17 } 18 if (stack.size() < len) stack.push(c); 19 } 20 StringBuffer res = new StringBuffer(); 21 while (!stack.isEmpty()) { 22 res.insert(0, stack.pop()); 23 } 24 while (res.length()>0 && res.charAt(0)=='0') { 25 res.deleteCharAt(0); 26 } 27 return res.toString(); 28 } 29 }
這道題跟Leetcode里面的那道Next Permutation很像,那個題要找比一個數大的下一個數,於是從這個數的右邊開始,找第一個遞減的位置所在。這道題也是類似,只不過從這個數的左邊開始,找第一個遞減的位置所在。那道題是想要改動的影響最小,所以從右邊開始掃描。這道題是想要改動的影響最大,所以從左邊開始掃描。
這道題,刪掉一個數,相當於用這個數后面的數代替這個數。所以后面這個數一定要比當前小才行。所以找的是第一個遞減的位置,把大的那個數刪了。
這樣做一次就是找到了:刪除哪一個數,使得剩下的數最小。對剩下的數再做k次,就可以找到刪除哪k個數,使得剩下的數最小。這其實是一個Greedy算法,因為這樣每做一次,得到的都是當前最優的結果。
看起來需要O(Nk)時間復雜度,但其實用一個Stack,再記錄pop了幾次,O(2N)就好了
1 public class Solution { 2 /** 3 *@param A: A positive integer which has N digits, A is a string. 4 *@param k: Remove k digits. 5 *@return: A string 6 */ 7 public String DeleteDigits(String A, int k) { 8 Stack<Integer> st = new Stack<Integer>(); 9 int popCount = 0; 10 StringBuffer res = new StringBuffer(); 11 for (int i=0; i<A.length(); i++) { 12 int num = (int)(A.charAt(i) - '0'); 13 if (st.isEmpty()) st.push(num); 14 else if (num >= st.peek()) { 15 st.push(num); 16 } 17 else { 18 if (popCount < k) { 19 st.pop(); 20 i--; 21 popCount++; 22 } 23 else { 24 st.push(num); 25 } 26 } 27 } 28 while (popCount < k) { 29 st.pop(); 30 popCount++; 31 } 32 while (!st.isEmpty()) { 33 res.insert(0, st.pop()); 34 } 35 while (res.length() > 1 && res.charAt(0) == '0') { 36 res.deleteCharAt(0); 37 } 38 return res.toString(); 39 } 40 }