【贪心 或 DFS - 面试题】小于n最大数

数组A中给定可以使用的1~9的数,返回由A数组中的元素组成的小于n(n > 0)的最大数。 例如:A = {1, 2, 4, 9},n = 2533,返回2499。

题解

贪心思路

题目很好理解,但没写对呜呜呜

cpp 复制代码
#include <iostream>
#include <vector>
#include <unordered_set>

using namespace std;

int getMaxD(vector<int> &a, int x)
{
    for (auto it = a.rbegin(); it != a.rend(); it++)
    {
        if (*it < x)
        {
            return *it;
        }
    }
    return 0;
}

int solve(vector<int> &a, int n)
{

    // 分解 n
    vector<int> nvec;
    while (n > 0)
    {
        int tmp = n % 10;
        nvec.push_back(tmp);
        n = n / 10;
    }

    // 排序可以使用的数组
    sort(a.begin(), a.end());
    // 记录有哪一些数字可以用
    unordered_set<int> st;
    for (auto v : a)
    {
        st.insert(v);
    }
    // 存储答案
    vector<int> ans(nvec.size());
    
    // 需要特判一下数组只有一个的情况
    if (a.size() == 1)
    {
        if (nvec[nvec.size() - 1] <= a[0])
        {
            int ans = 0;
            for (int i = 0; i < nvec.size() - 1; i++)
            {
                ans *= 10;
                ans += a[0];
            }
            return ans;
        }
        else
        {
            int ans = 0;
            for (int i = 0; i < nvec.size() - 1; i++)
            {
                ans *= 10;
                ans += a[0];
            }
            return ans;
        }
    }

    // 从给定的数字n的高位开始选择数字
    for (int i = nvec.size() - 1; i >= 0; i--)
    {
        cout << i << endl;
        // 除了最后一位,其他位数能找到和原来数n的位数一样的,那就优先选
        if (i > 0 && st.find(nvec[i]) != st.end())
        {
            ans[i] = nvec[i];
            continue; // 选完后直接跳过
        }
        // 如果没找到一样的数字
        // 那就找一个比nvec[i]小的数字
        // 如果找到了,那后面就不用比较了,直接选最大的数字就行
        // 所以直接跳出
        auto d = getMaxD(a, nvec[i]);
        if (d > 0)
        {
            ans[i] = d;
            break;
        }
        // 如果剩余数字都比当前n的位数上要大
        // 开始回溯,即上一位重新选择
        // 上一位通过getMaxD函数选择小于当前位数的数(从给定数字中)
        for (i++; i < nvec.size(); i++)
        {
            ans[i] = 0;
            cout << i << endl;
            // 如果有,那就直接跳出循环,剩余位数选最大值即可
            d = getMaxD(a, nvec[i]);
            if (d > 0)
            {
                ans[i] = d;
                break;
            }
            // 如果一直回溯到第一个数字了,都没找到合适的
            // 那说明和原来n数字一样长的答案不存在
            if (i == nvec.size() - 1)
            {
                cout << i << endl;
                ans.resize(nvec.size() - 1);
                cout << ans.size() << endl;
            }
        }
        break;
    }

    int res = 0;
    // cout << ans.size() << endl;
    for (int i = ans.size() - 1; i >= 0; i--)
    {
        res *= 10;
        if (ans[i] > 0)
        {
            res += ans[i];
            continue;
        }
        res += a.back();
    }
    return res;
}

int main()
{
    auto a = vector<int>{4};
    int n = 23333;
    int res = solve(a, n);
    cout << res << endl;
    return 0;
}

DFS

后面有空再补吧。

相关推荐
hnjzsyjyj1 天前
东方博宜OJ 2190:树的重心 ← 邻接表 or 链式前向星
数据结构·链式前向星·树的重心
yaoh.wang1 天前
力扣(LeetCode) 13: 罗马数字转整数 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
ChoSeitaku1 天前
NO15数据结构选择题考点|线性表|栈和队列|串
数据结构
T1ssy1 天前
布隆过滤器:用概率换空间的奇妙数据结构
算法·哈希算法
hetao17338371 天前
2025-12-12~14 hetao1733837的刷题笔记
数据结构·c++·笔记·算法
椰子今天很可爱1 天前
五种I/O模型与多路转接
linux·c语言·c++
一直都在5721 天前
数据结构入门:时间复杂度与排序和查找
数据结构
程序员zgh1 天前
C++ 互斥锁、读写锁、原子操作、条件变量
c语言·开发语言·jvm·c++
鲨莎分不晴1 天前
强化学习第五课 —— A2C & A3C:并行化是如何杀死经验回放
网络·算法·机器学习
搞科研的小刘选手1 天前
【ISSN/ISBN双刊号】第三届电力电子与人工智能国际学术会议(PEAI 2026)
图像处理·人工智能·算法·电力电子·学术会议