Lintcode: Delete Digits


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM