面試題——移掉k位數字

AcWing 1453 移掉 k 位數字

題目

給定一個以字符串表示的非負整數num,移除這個數中的k位數字,使得剩下的數字最小

注意:

  • 空字符串被視爲0
  • 如果結果中包含前導零,則需要將前導零刪除,最後刪除的前導零不用包含在移除的k個數字中

輸入格式

第一行輸入一個字符串,用來表示非負整數num

第二行輸入一個整數,表示k

輸出格式

輸出一個字符串,表示移除k位數字後所能得到的最小數字

數據範圍

0≤k≤字符串長度≤100000
num中不包含任何前導0

輸入樣例1:

1432219
3

輸出樣例1:

1219

樣例1解釋

移除掉三個數字4,3,2可形成一個新的最小的數字1219

輸入樣例2:

10200
1

輸出樣例2:

200

樣例2解釋:

移掉首位的1剩下的數字爲200,注意輸出不能有任何前導零

輸入樣例3:

10
2

輸出樣例3:

0

樣例3解釋

從原數字移除所有的數字,剩餘爲空就是0

思路

​ 這道題怎麼解呢,首先我們考慮一種特殊情況,當原字符串中的每一位都是按字典序排列時,越小的數字排的越靠前,所以要是想移除k位得到最小數字,只需要移除最後k位即可

​ 由此我們可以得到一個思路:將原字符串排序,移除後k位來獲得最小數字,但是這裏我們不考慮這種方法,接下來介紹另一種方法

​ 有序的情況我們分析了,那無序的呢?假設字符串是1, 5, 3, 2, 1,我們要想移除2位來獲得最小數字呢?

​ 我們先正常遍歷字符串,當遇到nums[i] > nums[i + 1]的情況時,爲了能使最後得到的數字最小,我們一定要移除排名更前且值更大的數字,因爲從數字的角度看,越大且排名越前的數字對整個數字的大小影響越大,比如190一定大於109

​ 還有一個問題就是前導零的問題,我們當得到了最後的結果之後,從頭遍歷一下數組,用i記住前面有幾個0最後返回時從i開始輸出就好啦,下面是代碼:

代碼

#include <iostream>
#include <string>

using namespace std;

int main() {
	string nums;
	int k;
	cin >> nums >> k;
	string res = "0";
	for (int i = 0; i < nums.size(); i++) {
		while (k && nums[i] < res.back()) {
			res.pop_back();
			k--;
		}
		res += nums[i];
	}
	while (k) {
		res.pop_back();
		k--;
	}
	int i = 0; 
	while (res[i] == '0')
		i++;
	if (i == res.size())
		puts("0");
	else
		cout << res.substr(i) << endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章