题目:给定一个包含0-9的若干个不重复数字的数组,如{1,2,5}等,求出比n小的最大值。
核心:贪心+回溯
步骤:
-
先排序给的nums数组
-
将n转化为string
-
遍历n,从高位到低位
-
当前位的数值如果可以从nums数组中找到,那么【结果集】的对应位上添加这个数字(比较的位数需要比原来的少最低位,因为要保证小于n);当前位的数值如果从nums数组中找不到,那么就找比当前位小且最大的数字,添加到【结果集】中并且跳出整个循环;当前位的数值如果无法在nums数组中找到比它小的数值,即nums数组的值都比当前位要大,那么最高位舍弃,即收缩一位,跳出整个循环;
-
最后拼接数字,【结果集】中非0数字就正常计算,如果是0那就选取nums数组的最大值。
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <unordered_set>
using namespace std;
//主要用来查找相同数字
int findEqualNum(const vector<int>& nums, int target)
{
int left = 0, right = nums.size() - 1;
while (left <= right)
{
int mid = left + ((right - left) >> 1);
if (nums[mid] < target)
{
left = mid + 1;
}
else if (nums[mid] > target)
{
right = mid - 1;
}
else
{
return nums[mid];
}
}
return -1;
}
//查找比target小且最大的数字
int findLessNum(const vector<int>& nums, int target)
{
int left = 0, right = nums.size() - 1;
while (left < right)
{
int mid = left + ((right - left + 1) >> 1);
if (nums[mid] < target) left = mid;
else right = mid - 1;
}
//数组中所有的数字都比target大
if (nums[left] > target && left == 0) return -1;
return nums[left];
}
int getMaxValue(int n, vector<int>& nums)
{
if (nums.empty()) return -1;
sort(nums.begin(), nums.end());
if (nums[0] >= n) return -1;
string strN = to_string(n);
vector<int> res(strN.size());
for (int i = 0; i < strN.size(); ++i)
{
//当前位能够从提供的数组中找到
if (i < strN.size() - 1 && findEqualNum(nums, strN[i] - '0') != -1)
{
res[i] = (strN[i] - '0');
continue;
}
//当前位找不到相等数字,但是能找到比当前位小且最大的数字
else if (findLessNum(nums, strN[i] - '0') != -1)
{
res[i] = findLessNum(nums, strN[i] - '0');
break;
}
//当前位比所有的数字都小
else
{
//回溯
for (i--; i >= 0; --i)
{
int value = findLessNum(nums, strN[i] - '0');
if (value != -1)
{
res[i] = value;
break;
}
res[i] = 0;
}
if (i == -1) res.resize(res.size() - 1);
break;
}
}
//拼接目标数字
int target = 0;
for (int i = 0; i < res.size(); ++i)
{
int val = res[i];
if (val > 0)
{
target = target * 10 + val;
}
else
{
target = target * 10 + nums.back();
}
}
return target;
}
int main()
{
int n = 999;
vector<int> nums1{ 1,7,9 };
cout << getMaxValue(n, nums1) << endl;
vector<int> nums2{ 1,7,9 };
cout << getMaxValue(2355, nums2) << endl;
vector<int> nums3{ 2,7,9 };
cout << getMaxValue(911, nums3) << endl;
return 0;
}
该文章介绍了一个使用C++实现的算法,通过贪心策略和回溯方法,从给定的无重复数字数组中找出比整数n小的最大值。首先对数组排序,然后逐位比较n的每一位,尝试找到相等或更小的数字,如果找不到则回溯并尝试更低的位。最后组合成结果并返回。
5188

被折叠的 条评论
为什么被折叠?



