加载中...

小于n的最大数

贪心+回溯:
找某位的最小值的时候用set实现的二分

求hack

#include <algorithm>
#include <unordered_set>
#include <vector>
#include <iostream>
using namespace std;
// getMaxDigitLtD 获取小于指定数字的最大数字。
int getMaxDigitLtD(const vector<int> &digits, int digit) {
	for (auto it = digits.rbegin(); it != digits.rend(); it++) {
		if (*it < digit) {
			return *it;
		}
	}
	return -1;
}

// getMaxNumLtN 获取小于 n 的最大数。
int getMaxNumLtN(vector<int> &digits, int n) {
	// 获取 n 的每一位数字。12345
	vector<int> ndigits;
	while (n > 0) {
		ndigits.push_back(n % 10);
		n /= 10;
	}
	// 排序给定的数字数组。 5 4 3 2 1 
	sort(digits.begin(), digits.end());
	// 数字写入 map 用于快速查看是否存在。
	unordered_set<int> set;
	for (auto v : digits) {
		set.insert(v);
	}
	
	// 目标数的每一位数字。
	vector<int> tdigits(ndigits.size(),-1);
	
	// 从原数字高位到低位遍历,尽可能地取相同值,除了最后一位,最后一位需要比他小。
	for (int i = ndigits.size() - 1; i >= 0; i--) {
		// 存在相同的数字,可以直接看下一位(最后一位除外)。
		if (i > 0 && set.find(ndigits[i]) != set.end()) {
			tdigits[i] = ndigits[i];
			continue;
		}
		
		// 找不到相同的数字,那就找到存在小于当前位的最大数字。
		// 如果最高位真的找到比他小的,说明之后数字都可以取nums最大 ,break 
		// 123 直接放99 
		// 213 直接放09 
		auto d = getMaxDigitLtD(digits, ndigits[i]);
		if (d != -1) {
			tdigits[i] = d;
			break;
		}
		
		// 找不到比当前位小的,需要回溯。数组{2} target:219 2xy
		// 现在x=2就已经无敌了  
		for (i++; i < ndigits.size(); i++) {
			tdigits[i] = 0;
			// 之前可能设置的是相等,小于当前位的最大数字。
			d = getMaxDigitLtD(digits, digits[i]);
			if (d != -1) {
				tdigits[i] = d;
				break;
			}
			// 最高位也没有小于其的最大数字。
			if (i == ndigits.size() - 1) {
				tdigits.resize(tdigits.size() - 1);
			}
		}
		break;
	}
	
	// 拼装目标数。
	int target = 0;
	for (int i = tdigits.size() - 1; i >= 0; i--) {
		target *= 10;
		if (tdigits[i] != -1) {  
			target += tdigits[i];
			continue;
		}
		// 取数字数组中最大的数字。
		target += digits.back();
	}
	return target;
}

int main() {
	
	
	auto digits = vector<int>{2, 0};
	cout << getMaxNumLtN(digits, 219) << endl;
	
	
	digits = vector<int>{0, 2, 9, 4};
	cout << getMaxNumLtN(digits, 2533) << endl;
	
	digits = vector<int>{1, 2, 5, 4};
	cout << getMaxNumLtN(digits, 2543) << endl;
	
	digits = vector<int>{1, 2, 5, 4};
	cout << getMaxNumLtN(digits, 2541) << endl;
	
	digits = vector<int>{1, 2, 9, 4};
	cout << getMaxNumLtN(digits, 2111) << endl;
	
	
}

posted @ 2024-09-22 01:27  liang302  阅读(30)  评论(0编辑  收藏  举报