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更小。
那么,如果去掉多个数字怎么办呢?
如果每次去掉一位,并保证去掉数字后得到的数是最小的,那么通过递归,得到的数也必定是最小的。
结论:
我们从左向右查找:
如果前一位比后一位大,那么去掉前一位,得到最小的数。
如果每一位都比后一位小,去掉最后一位,得到最小的数。