1. 程式人生 > >LeetCode-402.Remove K Digits

LeetCode-402.Remove K Digits

0.原題

Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

Note:

  • The length of num is less than 10002 and will be ≥ k.
  • The given num does not contain any leading zero.

Example 1:

Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.

Example 2:

Input: num = "10200", k = 1
Output: "200"
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.

Example 3:

Input: num = "10", k = 2
Output: "0"
Explanation: Remove all the digits from the number and it is left with nothing which is 0.

 

1.程式

class Solution:
    def removeKdigits(self, num, k):
        """
        :type num: str
        :type k: int
        :rtype: str
        """
        result = self.fun(num,k)
        if result == '':
            result = '0'
        else:
            result = str(int(result))
        return result

    def fun(self,num,k):
        if k == 0:
            return num
        else:
            length = len(num)
            for i in range(length-1):
                if num[i] > num[i+1]:
                    new_num = num[:i] + num[i+1:]
                    result = self.fun(new_num,k-1)
                    return result
            new_num = num[:length-1]
            result = self.fun(new_num,k-1)
            return result

if __name__ == '__main__':
    num = '10'
    k = 2
    solution = Solution()
    result = solution.removeKdigits(num,k)
    print(result)

 

2.解題思路

本題中最大數字長度為10002,這顯然是一個非常大的數,如果使用遍歷暴力求解,當然不合適。

因此,本題的重點在於要找到數字Remove的最佳方法。

首先,我們根據常識可知:

  • 不同位置的數字具有不同的權重;
  • 若高位數字不同,則高位上的數字越小,則這個數越小;
  • 若高位數字相同,則次高位上的數字越小,則這個數越小;

再看一個例子,我們從左向右,嘗試依次去掉一位:

  • 1432219,去掉1,則剩下432219;
  • 1432219,去掉4,則剩下132219;   最小
  • 1432219,去掉3,則剩下142219;
  • 1432219,去掉2,則剩下143219;
  • 1432219,去掉2,則剩下143219;
  • 1432219,去掉1,則剩下143229;
  • 1432219,去掉9,則剩下143221;

當我們只去掉一位的時候,從左往右查詢,每次查詢相鄰的兩個數字:

  • 如果左邊的數字比右邊的大,那麼去掉左邊的數字,這個數最小。比如,21xxx,去掉2得到1xxx,去掉1得到2xxx;顯然,1xxx更小。
  • 如果左邊的數字比右邊的小,那麼去掉右邊的數字,這個數較小。但需要注意的是,去掉右邊的數字得到的數不一定是最小的,因為右邊數字的下一位,可能是更大的數。比如,123xxx,去掉2得到13xxx,去掉3得到12xxx;顯然,12xxx更小。

那麼,如果去掉多個數字怎麼辦呢?

如果每次去掉一位,並保證去掉數字後得到的數是最小的,那麼通過遞迴,得到的數也必定是最小的。

 

結論:

我們從左向右查詢:

如果前一位比後一位大,那麼去掉前一位,得到最小的數。

如果每一位都比後一位小,去掉最後一位,得到最小的數。