貪婪策略:數字去掉幾位求最小值實現
阿新 • • 發佈:2018-12-23
問題分析
在位數固定的前提下,讓高位的數字儘量小,其值就較小。依據此貪婪策略就可以解決這個問題。
如何根據貪婪策略刪除數字呢?總目標是刪除高位較大的數字,具體地相鄰兩位比較,若高位比低位大則刪除高位。
程式碼一般實現:
package com.demo.test.util; /** * @description: 給定一個整數,刪除k個數後,使得剩餘值最小 * @author: fengze * @create: 2018-11-28 11:37 **/ public class TestRemoveBig { public static String getOptimalValue(String value, int k) { //校驗輸入值和刪除個數關係 if (value.length() <= k) { return "0"; } //外層迴圈控制刪除次數 for (int j = 0; j < k; j++) { //內層迴圈控制比較次數 boolean flag = false; for (int i = 0; i < value.length() - 1; i++) { if (value.charAt(i) > value.charAt(i + 1)) { value = value.substring(0, i) + value.substring(i + 1); flag = true; //每次迴圈刪除一個數 break; } } //未刪除數時,將最後一個值刪除 if (!flag) { value = value.substring(0, value.length() - 1); } //移除前面為0的所有數值 removeZero(value); } if (value.length() == 0){ return "0"; } return value; } private static void removeZero(String value) { for (int i = 0; i < value.length(); i++) { if (value.charAt(i) != '0') break; value = value.substring(1, value.length()); } } public static void main(String[] args) { System.out.println(getOptimalValue("15397268",8)); } }
效率分析:
1.每一次內層迴圈,都需要從頭遍歷所有數字
2.subString方法本身效能不高
subString方法的底層實現,涉及到了新字串的建立,以及逐個字元的拷貝。這個方法自身的時間複雜度是O(n)。因此,我們應該避免在每刪除以後數字後就呼叫subString方法。
高效率實現:
package com.demo.test.util; /** * @description: 給定一個整數,刪除k個數後,使得剩餘值最小(優化實現方案) * @author: fengze * @create: 2018-11-28 13:38 **/ public class TestRemoveBigOptimal { public static String getOptimalValue(String value, int k) { //校驗輸入值和刪除個數關係 if (value.length() <= k) { return "0"; } //刪除後剩餘位數 int newLenth = value.length() - k; //使用陣列將剩餘元素收集 char[] newValue = new char[newLenth]; //棧頂元素 int stackTop = 0; //遍歷元素,將符合要求的刪除,不符合要求的放入陣列中 for (int i = 0; i < value.length() ; i++) { //判斷陣列最後放入元素是否比當前值大,大就更換;第一次不進入 while (stackTop > 0 && newValue[stackTop-1] > value.charAt(i) && k>0) { stackTop--; k--; } //更換符合要求數值 newValue[stackTop++] = value.charAt(i); } //找到陣列中第一個非0數值 int zeroNum = 0; while(zeroNum < newLenth && newValue[zeroNum] == '0'){ zeroNum++; } //返回結果 return zeroNum == newLenth ? "0" : new String(newValue,zeroNum,newLenth-zeroNum); } public static void main(String[] args) { System.out.println(getOptimalValue("103970609",4)); } }
程式碼中非常巧妙地運用了棧的特性,在遍歷原整數的數字時,讓所有數字一個個入棧,當某個數字需要刪除時,讓該數字出棧。最後,程式把棧中的元素轉化為字串結果。
程式碼只對所有數字遍歷了一趟,遍歷的時間複雜度是O(n),而後把棧轉化為字串的時間複雜度也是O(n),所以最終的時間複雜度是O(n)。
同時,程式中利用棧來回溯遍歷過的數字以及刪除數字,所以程式的空間複雜度是O(n)。