小于n的最大数

算法题:问题描述:给一个数组nums=[5,4,8,2],给一个n=5416, 让你从nums中选出一些元素,使得组成的数字是小于n的最大数

java 复制代码
import java.util.Arrays;

public class FindMaxNumberLessThanTarget {
    public static void main(String[] args) {
        // 定义数组 nums
        int[] nums = {5, 6, 8, 7};
        // 定义目标值 target
        int target = 500;
        // 对数组进行排序
        Arrays.sort(nums);
        // 将目标值转换为字符串,方便逐位处理
        String targetStr = String.valueOf(target);
        // 调用 getMaxNumbers 方法获取小于目标值的最大数字
        int result = getMaxNumbers(nums, targetStr);
        // 输出结果
        System.out.println(result);
    }

    // 二分查找方法,用于在 nums 中找到小于等于 target 的最大数字
    public static int search(int[] nums, int target) {
        // 初始化二分查找的左边界
        int low = 0;
        // 初始化二分查找的右边界
        int high = nums.length - 1;
        // 二分查找循环
        while (low < high) {
            // 计算中间位置,使用 (high - low + 1) / 2 避免整数溢出
            int mid = low + (high - low + 1) / 2;
            // 如果中间位置的数字小于等于目标值
            if (nums[mid] <= target) {
                // 更新左边界为中间位置
                low = mid;
            } else {
                // 否则更新右边界为中间位置减 1
                high = mid - 1;
            }
        }
        // 如果左边界对应的数字小于等于目标值,返回该数字,否则返回 -1
        return nums[low] <= target ? nums[low] : -1;
    }

    // 主方法,用于构建小于目标值的最大数字
    public static int getMaxNumbers(int[] nums, String target) {
        // 用于存储构建的数字的每一位
        int[] res = new int[target.length()];
        // 最终结果
        int ans = 0;
        // 标记是否已经确定了小于目标值的最大数字
        boolean flag = false;
        // 遍历目标值的每一位
        for (int i = 0; i < target.length(); i++) {
            // 如果已经确定了小于目标值的最大数字
            if (flag) {
                // 直接将 nums 中的最大值添加到 res 中
                res[i] = nums[nums.length - 1];
                continue;
            }
            // 获取当前位的数字
            int subtarget = target.charAt(i) - '0';
            // 调用 search 方法,找到小于等于当前位的最大数字
            int temp = search(nums, subtarget);
            // 如果没有找到合适的数字
            if (temp == -1) {
                // 如果是第一位
                if (i == 0) {
                    // 如果目标值长度为 1,返回 0
                    if (target.length() == 1) {
                        return 0;
                    } else {
                        // 否则返回由 nums 中最大值重复 target.length() - 1 次组成的数字
                        StringBuilder sb = new StringBuilder();
                        for (int j = 0; j < target.length() - 1; j++) {
                            sb.append(nums[nums.length - 1]);
                        }
                        return Integer.parseInt(sb.toString());
                    }
                } else {
                    // 向前回溯,尝试找到一个合适的数字
                    int index = i - 1;
                    while (temp == -1 && index >= 0) {
                        temp = search(nums, target.charAt(index) - '0' - 1);
                        index--;
                    }
                    // 如果仍然没有找到合适的数字
                    if (temp == -1) {
                        // 返回由 nums 中最大值重复 target.length() - 1 次组成的数字
                        StringBuilder sb = new StringBuilder();
                        for (int j = 0; j < target.length() - 1; j++) {
                            sb.append(nums[nums.length - 1]);
                        }
                        return Integer.parseInt(sb.toString());
                    }
                    // 更新 res 中相应位置的数字
                    res[index + 1] = temp;
                    // 将中间位置的数字设为 nums 中的最大值
                    for (int j = index + 2; j < i; j++) {
                        res[j] = nums[nums.length - 1];
                    }
                    // 将当前位设为 nums 中的最大值
                    res[i] = nums[nums.length - 1];
                    // 标记已经确定了小于目标值的最大数字
                    flag = true;
                }
            } else {
                // 如果找到的数字等于当前位
                if (temp == subtarget) {
                    // 将该数字添加到 res 中
                    res[i] = temp;
                } else {
                    // 否则将该数字添加到 res 中,并标记已经确定了小于目标值的最大数字
                    res[i] = temp;
                    flag = true;
                }
            }
        }
        // 将 res 中的数字组合成一个整数
        for (int i = 0; i < res.length; i++) {
            ans = ans * 10 + res[i];
        }
        // 返回最终结果
        return ans;
    }
}    

代码的整体思路

  1. 对数组 nums 进行排序,以便后续查找合适的数字。
  2. 把目标值 target 转换为字符串,方便逐位处理。
  3. 定义 search 函数,借助二分查找从 nums 里找出小于等于给定值的最大数字。
  4. 定义 getMaxNumbers 函数,通过遍历目标值的每一位,逐步构建小于目标值的最大数字。
  5. 最终输出构建好的最大数字。
相关推荐
瑾修1 小时前
golang查找cpu过高的函数
开发语言·后端·golang
yangminlei7 小时前
Spring Boot3集成LiteFlow!轻松实现业务流程编排
java·spring boot·后端
计算机毕设VX:Fegn08958 小时前
计算机毕业设计|基于springboot + vue医院设备管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
J_liaty8 小时前
Spring Boot整合Nacos:从入门到精通
java·spring boot·后端·nacos
面汤放盐8 小时前
后端系统设计文档模板
后端
2***d8859 小时前
SpringBoot 集成 Activiti 7 工作流引擎
java·spring boot·后端
五阿哥永琪9 小时前
Spring中的定时任务怎么用?
java·后端·spring
追逐时光者9 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 65 期(2026年1.1-1.11)
后端·.net
计算机毕设VX:Fegn08959 小时前
计算机毕业设计|基于springboot + vue小型房屋租赁系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
gelald9 小时前
AQS 工具之 CountDownLatch 与 CyclicBarry 学习笔记
java·后端·源码阅读