小于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. 最终输出构建好的最大数字。
相关推荐
Huazie34 分钟前
在WSL2 Ubuntu中部署FastDFS服务的完整指南
服务器·后端·ubuntu
行者无疆xcc1 小时前
【Django】设置让局域网内的人访问
后端·python·django
嘵奇2 小时前
基于Spring Boot实现文件秒传的完整方案
java·spring boot·后端
Value_Think_Power2 小时前
azure 一个 pod 内有多个 container ,这些container 可以 共享一块磁盘吗
后端
李菠菜2 小时前
优化Centos关闭SELinux/Swap及资源限制调整
linux·后端·centos
wangyongquan2 小时前
koa语法 | koa/router | 中间件 | 洋葱模型
后端·node.js
小兵张健2 小时前
小米 JD 调研
java·后端·面试
BigTopOne2 小时前
【君正-T41】外设采集h264流程
后端
caihuayuan52 小时前
JavaScript数据结构与算法实战: 探秘Leetcode经典题目
java·大数据·spring boot·后端·课程设计
编程轨迹2 小时前
Spring 微服务技巧:使用环境变量抽象数据库主机名
后端