小于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. 最终输出构建好的最大数字。
相关推荐
lgily-122523 分钟前
常用的设计模式详解
java·后端·python·设计模式
意倾城1 小时前
Spring Boot 配置文件敏感信息加密:Jasypt 实战
java·spring boot·后端
火皇4051 小时前
Spring Boot 使用 OSHI 实现系统运行状态监控接口
java·spring boot·后端
薯条不要番茄酱2 小时前
【SpringBoot】从零开始全面解析Spring MVC (一)
java·spring boot·后端
懵逼的小黑子9 小时前
Django 项目的 models 目录中,__init__.py 文件的作用
后端·python·django
小林学习编程10 小时前
SpringBoot校园失物招领信息平台
java·spring boot·后端
java1234_小锋12 小时前
Spring Bean有哪几种配置方式?
java·后端·spring
柯南二号13 小时前
【后端】SpringBoot用CORS解决无法跨域访问的问题
java·spring boot·后端
每天一个秃顶小技巧14 小时前
02.Golang 切片(slice)源码分析(一、定义与基础操作实现)
开发语言·后端·python·golang
gCode Teacher 格码致知15 小时前
《Asp.net Mvc 网站开发》复习试题
后端·asp.net·mvc