题目描述: 数组A中给定可以使用的1~9的数,返回由A数组中的元素组成的小于n(n > 0)的最大数。例如:A = {1, 2, 4, 9},n = 2533,返回2499。
该题许多方法用dfs去做,我用非递归的方法去模拟,请各位大佬看看有没有问题。
大致思路
int maxNum(int n, vector<int> nums)
{
sort(nums.begin(), nums.end());
if (n <= nums[0]) return -1;
string s = to_string(n);
vector<int> ans;
for(int i=0;i<s.length();i=ans.size())
{
// 碰到需要回溯的情况,将能变小的第一个数字变小一个,后面的所有数字填最大值即可
// 边界1:当前数字小于提供的nums的最小值
// 边界2:最后一位数等于提供的nums的最小值
if (s[i] - '0' < nums[0]||(i==s.length()-1&&s[i]-'0'==nums[0]))
{
//回溯到数字可减小的位置,并将这个位置的数减小一个
while (ans.size() > 1 && ans.back() == 0)
{
ans.pop_back();
}
ans[ans.size() - 1]--;
//后面的所有数字填最大值
for (int j = ans.size(); j < s.length(); j++)
{
ans.push_back(nums.size() - 1);
}
}
// 正常往后添加符合条件最大的数字
else
{
//可用二分去优化
for (int j = nums.size() - 1; j >= 0; j--)
{
if (s[i] - '0' > nums[j])
{
ans.push_back(j);
// 因为当前添加的数字小于n,因此后面的数字选最大数就行
for (int p = ans.size(); p < s.length(); p++)
ans.push_back(nums.size()-1);
break;
}
// 最后一位数不能相等,否则两个数就完全相等了
else if (s[i] - '0' == nums[j]&&i!= s.length() - 1)
{
ans.push_back(j);
break;
}
}
}
}
// 将数组转换成数字
int x = 0;
for (auto a : ans)
{
if(a>=0)
x = x * 10 + nums[a];
}
return x;
}