一、題目描述
給出乙個整數,從該整數中去除k個數字,要求剩下的數字形成的新整數盡可能小。
如:1593212,刪除3個數字後的,新整數的最小情況是1212
30200,刪除乙個數字,新整數的最小情況是200
二、解題思路
這個題可以用貪心演算法來解,每次求出刪除乙個數字後,讓剩下數字形成的新整數達到最小。
像這樣依次取得區域性最優解,最終得到全域性最優解的思想,叫做貪心演算法。
如何做到刪除乙個整數後,讓剩下的數字最小呢?
其主要思想是把高位的數字降低。把原整數的所有數字從左到右進行比較,如果發現某一位數字大於它右面的數字,那麼在刪除該數字後,必然會使該數字的值降低,因為右面比他小的數字頂替了它的位置。
如:41270936,4>1,所以把4去除,資料變為1270936;1<2、2<7、7>0,7大於它右邊的數字,所以把7刪除,資料變為120936;以此類推,直至刪除完要求的k個數字。
**實現:
def
remove_k_digits
(num,k)
:for i in
range(0
,k):
has_cut=
false
for j in
range(0
,len
(num)):
if num[j]
>num[j+1]
: num=num[
:j]+num[j+1:
] has_cut=
true
break
# 如果沒有找到要刪除的數字,則刪除最後乙個數字
ifnot has_cut:
num=num[
:len
(num)-1
]# 清除整數左側的0
for j in
range(0
,len
(num)):
if num[0]
!=0:break
num=num[1:
]# 如果所有整數都已經刪除了,直接返回0
上述**的時間複雜度為o(kn)。
以上還可以進行效能的優化:
1、每一次內層迴圈都需要從頭開始遍歷所有的數字,比如:11 111 111 111 114 132 ,第一次遍歷到數字4,發現4>1,從而刪除4,但是下次還要從頭開始遍歷。我們可以停留在上一次刪除位置,等下一輪開始時繼續進行比較,而不是再次從頭開始遍歷。
2、字串擷取方法本身效能不高
字串擷取方法的底層實現,涉及新字串的建立以及逐個字元的複製。這個方法自身的時間複雜度是o(n)。
優化方法:
以遍歷數字作為外迴圈,以k作為內迴圈;在遍歷原數字時,讓所有數字乙個乙個入棧,當某個數字需要被刪除時,讓數字出棧。
以541270936 ,k=3為例:
遍歷5,數字5入棧;遍歷到數字4,讓它和棧頂元素比較,發現5>4,數字5出棧,數字4入棧,k減1;遍歷到數字1,4>1,4出棧,1入棧,k減1;遍歷2,1<2,2入棧;遍歷到7,2<7,7入棧;遍歷到0, 7>0,7出棧,0入棧,k減1。此時k為0,把剩下的數字一起入棧,此時棧中元素就是最終結果。
這種方法只對所有數字遍歷了一次,遍歷的時間複雜度是o(n),把棧轉化為字串的時間複雜度也是o(n),所以最終的時間複雜度是o(n)。
**實現:
def
remove_k_digits_v2
(num,k)
:# 新整數的最終長度=原整數長度-k
new_length=
len(num)
-k # 建立乙個棧,用於接收數字
stack=
for i in
range(0
,len
(num)):
c=num[i]
# 這裡應該使用while迴圈而不是if,如果棧中多個連續元素都是大於c的,應該依次彈出
while
len(stack)
>
0and stack[
len(stack)-1
]>c and k>0:
stack.pop(
) k -=
1# 如果遇到數字0,且棧為空,數字0不入棧
if'0'
==c and
len(stack)==0
: new_length -=
1if new_length <=0:
return
"0"continue
# 當前數字入棧
# 找到棧中第乙個非0數字的位置,以此構建新的整數字串
if new_length <=0:
return
"0"return
''.join(stack)
print
(remove_k_digits_v2(
'1593212',3
))print
(remove_k_digits_v2(
'541270936',3
))
刪去k個數字後的最小值(貪心演算法思想實現)
題目 給出乙個整數,從該整數中去掉k個數字,要求剩下的數字形成的新整數盡可能小。解題思路 實現 刪除整數的k個數字,獲得刪除後的最小值 param num 原整數 param k 刪除數量 return 返回刪除後的最小值 public static string removekdigits str...
刪去k個數字後的最小值
參考 程式設計師小灰 substring 方法返回字串的子字串。語法public string substring int beginindex 或public string substring int beginindex,int endindex 引數beginindex 起始索引 包括 索引從...
刪除數字求最小值(貪心)
演算法分析 我們可以很容易的發現該題目可以使用貪心演算法。比如,上述正整數5476579228,要刪除k 4個數字獲得乙個最小的6位數字。然而我們知道剩下的6位數的首位不可能從54765 79228不可能從79228中得到 why?因為題目要求要按照原來正整數的左右次序排列,如果在79228中刪除後...